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 }
原文地址:https://www.cnblogs.com/evasean/p/7204566.html