• Coursera Algorithms week1 查并集 练习测验:3 Successor with delete


    题目原文:

    Given a set of n integers S = {0,1,,N-1}and a sequence of requests of the following form:

    • Remove from S
    • Find the successor of x: the smallest in such thaty>=x

    design a data type so that all operations(except construction) take logarithmic time or better in the worst case.

    分析

    题目的要求有一个0~n-1的顺序排列序列S,从S中移除任意x,然后调用getSuccessor(x),方法将返回一个y,这个y是剩余还在S中满足y>=x的最小的数。举例说明S={0,1,2,3,4,5,6,7,8,9}时

    remove 6,那么getSuccessor(6)=7

    remove 5,那么getSuccessor(5)=7

    remove 3,那么getSuccessor(3)=4

    remove 4,那么getSuccessor(4)=7

    remove 7,那么getSuccessor(7)=8, getSuccessor(3)=8

    而对于没有remove的数x,getSuccessor(x)应该等于几呢?题目没有说,那么就认为等于自身好了,接着上面,getSuccessor(2)=2

    根据上面的例子,可以看出,实际上是把所有remove的数做了union,root为子集中的最大值,那么getSuccessor(x)实际就是获取remove数中的最大值+1,根据这个思路,代码如下

     1 import edu.princeton.cs.algs4.StdOut;
     2 
     3 public class Successor {
     4     private int num;
     5     private int[] id;
     6     private boolean[] isRemove;
     7 
     8     public Successor(int n){
     9         num = n; 
    10         id = new int[n];
    11         isRemove = new boolean[n];
    12         for (int i = 0; i < n; i++) {
    13             id[i] = i;
    14             isRemove[i] = false;
    15         }
    16     }
    17 
    18     public int find(int p) {
    19         while (p != id[p])
    20             p = id[p];
    21         return p;
    22     }
    23 
    24     public void union(int p, int q) {
    25         //此处的union取较大根
    26         int pRoot = find(p);
    27         int qRoot = find(q);
    28         if (pRoot == qRoot)
    29             return;
    30         else if (pRoot < qRoot)
    31             id[pRoot] = qRoot;
    32         else
    33             id[qRoot] = pRoot;
    34     }
    35     
    36     public void remove(int x) {
    37         isRemove[x] = true;
    38         //判断相邻节点是否也被remove掉了,如果remove掉就union
    39         if (x>0 && isRemove[x-1]){
    40             union(x,x-1);
    41         }
    42         if (x<num-1 && isRemove[x+1]){
    43             union(x,x+1);
    44         }
    45     }
    46 
    47     public int getSuccessor(int x) {
    48         if(x<0 || x>num-1){//越界异常
    49             throw new IllegalArgumentException("访问越界!");
    50         }else if(isRemove[x]){
    51             if(find(x)+1 > num-1) //x以及大于x的数都被remove掉了,返回-1
    52                 return -1;    
    53             else //所有remove数集中最大值+1,就是successor
    54                 return find(x)+1;
    55         }else {//x未被remove,就返回x自身
    56             return x;
    57         }
    58     }
    59 
    60     public static void main(String[] args) {
    61         Successor successor = new Successor(10);
    62         successor.remove(2);
    63         successor.remove(4);
    64         successor.remove(3);
    65         StdOut.println("the successor is : " + successor.getSuccessor(3));
    66         successor.remove(7);
    67         successor.remove(9);
    68         StdOut.println("the successor is : " + successor.getSuccessor(9));
    69     }
    70 }
  • 相关阅读:
    背包九讲
    最小生成树 prime + 队列优化
    最小生成树 prime poj1287
    树状数组--转载
    O(n)求1-n的逆元
    数据结构--线段树
    博弈
    RMQ 数据结构
    BZOJ3687 计算子集和的异或和
    Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)D Dense Subsequence
  • 原文地址:https://www.cnblogs.com/evasean/p/7204566.html
Copyright © 2020-2023  润新知