382. 链表随机节点-哈希表法
给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点 被选中的概率一样 。
实现 Solution 类:
Solution(ListNode head) 使用整数数组初始化对象。
int getRandom() 从链表中随机选择一个节点并返回该节点的值。链表中所有节点被选中的概率相等。
示例:
输入
[“Solution”, “getRandom”, “getRandom”, “getRandom”, “getRandom”, “getRandom”]
[[[1, 2, 3]], [], [], [], [], []]
输出
[null, 1, 3, 2, 2, 3]
解释
Solution solution = new Solution([1, 2, 3]);
solution.getRandom(); // 返回 1
solution.getRandom(); // 返回 3
solution.getRandom(); // 返回 2
solution.getRandom(); // 返回 2
solution.getRandom(); // 返回 3
// getRandom() 方法应随机返回 1、2、3中的一个,每个元素被返回的概率相等。
这题不建议学习,博主写的方法有点复杂,解题代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
#define size_ts 100000
struct hash{
int val;
struct hash *next;
};
typedef struct {
struct hash *h;
int length;
} Solution;
int sizez;
int index_h[100000];
double p_s[100000];
void add_hash(struct hash *h,int val){
struct hash *p=(struct hash *)malloc(sizeof(struct hash ));
p->val=val;
p->next=h->next;
h->next=p;
}
Solution* solutionCreate(struct ListNode* head) {
sizez=0;
Solution *hs=(Solution*)malloc(sizeof(Solution)*size_ts);
for(int i=0;i<size_ts;i++){
(hs+i)->h=(struct hash *)malloc(sizeof(struct hash ));
(hs+i)->h->next=NULL;
(hs+i)->length=0;
}
int count=0;
while(head){
count++;
if((hs+abs(head->val)%size_ts)->h->next==NULL){
// printf("|%d ",(head->val)%size_ts);
index_h[sizez++]=abs(head->val)%size_ts;
}
add_hash((hs+abs(head->val)%size_ts)->h,head->val);
(hs+abs(head->val)%size_ts)->length=(hs+abs(head->val)%size_ts)->length+1;
head=head->next;
}
for(int i=0;i<sizez;i++){
p_s[i]=(hs+index_h[i])->length/1.0/count;
}
return hs;
}
int solutionGetRandom(Solution* obj) {
float b=rand()/(RAND_MAX+1.0);
for(int i=0;i<sizez;i++){
printf(" %f ",p_s[i]);
}
printf(" %f ",b);
int random1=-1;
for(int i=0;i<sizez;i++){
if(p_s[i]>=b){
random1=i;
break;
}
else{
b=b-p_s[i];
}
}
int random2=rand()%((obj+index_h[random1])->length);
struct hash *p=(obj+index_h[random1])->h->next;
// printf("%d ||",random2);
while(random2){
p=p->next;
random2--;
}
return p->val;
}
void solutionFree(Solution* obj) {
}
/**
* Your Solution struct will be instantiated and called as such:
* Solution* obj = solutionCreate(head);
* int param_1 = solutionGetRandom(obj);
* solutionFree(obj);
*/