我正在使用称为开放式哈希的技术来实现自己的集合RandomizedSet
。我必须创建一个函数,该函数返回集合中的一个随机元素,条件是所有元素的选择概率必须相同,并且该函数的平均值应为O(1)时间。这就是我的代码的样子。
我的课程SetNode
class SetNode{
int val;
SetNode next;
public SetNode(int x){
val = x;
}
}
我的课程RandomizedSet
class RandomizedSet {
int size;
ArrayList<SetNode> buckets;
int numBuckets;
/** Initialize your data structure here. */
public RandomizedSet() {
size = 0;
numBuckets = 10;
buckets = new ArrayList<>();
}
/** Returns the index in the ArrayList where the value will be found */
public int getBucketIndex(int val){
String str = Integer.parseInt(val);
int hashcode = Math.abs(str.hashCode());
return hashcode % numBuckets;
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
public boolean insert(int val) {
int index = getBucketIndex(val);
SetNode head = buckets.get(index);
while(head != null){
if(head.val == val){
return false;
}
head = head.next;
}
size++;
head = buckets.get(index);
SetNode temp = new SetNode(val);
temp.next = head;
buckets.set(index, temp);
if((1.0*size)/numBuckets >= 0.7){
doubleSize();
}
return true;
}
/** Doubles the size of the ArrayList to include more nodes */
public doubleSize(){
ArrayList<NodeSet> temp = buckets;
buckets = new ArrayList<>();
numBuckets = 2*numBuckets;
for(int i = 0; i < numBuckets; i++){
buckets.add(null);
}
for(SetNode s : temp){
SetNode head = s;
while(head != null){
insert(head.val);
head = head.next;
}
}
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
public boolean remove(int val) {
int index = getBucketIndex(val);
SetNode head = buckets.get(index);
SetNode prev = null;
while(head != null){
if(head.val == val){
break;
}
prev = head;
head = head.next;
}
if(head == null){
return false;
}
size--;
if(prev != null){
prev.next = head.next;
}
else{
buckets.set(index, head.next;)
}
return true;
}
/** Get a random element from the set. */
public int getRandom() {
}
}
我制作函数getRandom()
的主要想法是生成一个介于0和numBuckets
之间的随机数,但是这行不通,因为我可以有空的存储桶(填充有null的存储桶)并且一个存储桶中有很多元素,因此概率将不相等。
关于我该如何处理的任何想法?
答案 0 :(得分:0)
我对Java很陌生,但是我敢肯定这应该可行。创建一个while循环并像您一样生成整数。一旦找到其中包含值的存储桶,则从while循环中断。这也应具有相等的随机分布。
public int getRandom() {
while (true) {
int random = (int) (Math.random() * (buckets.size() + 1));
if (buckets.get(random) != null) {
return random;
}
}
}