A1
引入
有1个经理M,三名员工a,b,c,三名员工的薪水分别是x,y,z,M,a,b,c四个人可以任意交流沟通。
问:在满足以下规则的时候,经理如何可以知道三名员工的平均薪水?(x+y+z)/3
a.交流过程中:经理M不可以知道x,y,z的确切值
b.交流过程中:对于每个员工,不可以知道另外两人薪水的确切值(a不知道y,z; b不知道x,z;c不知道x,y)
提示:除了交流,他们还可以利用日常生活中的一切内容,来完成这件事(只要满足规则)
经理抛出一个随机数给A,A将随机数加上自己的工资丢给B,以此类推....
预备知识:链表基础
struct ListNode{
int val;//存储元素的数据域
ListNode *next;
};
例题
例1-a 206.Reverse Linked List
已知链表头节点指针head,将链表逆序。(不可申请额外空间)
class Solution{
public:
ListNode* reverseList(ListNode* head){
ListNode *new_head = NULL;
while(head){
ListNode *next=head->next;
head->next=new_head;
new_head = head;
head = next;
}
return new_head;
}
};
例1-b 92.Reverse Linked List Ⅱ
已知链表头节点指针head,将涟表从位置m到n逆序。(不申请额外空间,1<=m<=n<=链表长度)
class solution {
public:
ListNode* reverseBetween(ListNode* head, int m,int n) {
int change_len = n - m + 1;//计算需要逆置的节点个数
ListNode *pre_head = NULL;//初始化开始逆置的节点的前驱
ListNode *result = head;//最终转换后的链表头节点,非特殊情况即为head
while (head && —-m){//将head向前移动m-1个位置
pre_head = head;//记录前驱
head = head->next;
}//将modify_list_tail指向当前的head,即逆置后的链表尾
ListNode *modify_list_tail = head;
ListNode *new_head = NULL;
while(head && change_len){//逆置change_len个节点
ListNode *next = head->next;
head->next =new_head;
new_head = head;
head = next;
change_len--;
}
modify_list_tail->next=head;
if(pre_head) {
//如果pre_head不空,说明不是从第一个节点开始逆置的m>1
pre_head->next=new_head;
}
else{
result = new_head;
}
return result;
例2 160.Intersection of Two Linked Lists
已知链表A的头节点指针headA,链表B的头节点指针headB,两个链表相交,求两链表交点对应的节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution1 {//简单但复杂度高,利用集合
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
std: : set<ListNode*> node_set//设詈查找集合node_set
while (headA) {
node_set.insert(headA);//将链表A的节点插入set
headA=headA->next;
}
while(headB){
if(node_set.find(headB)!=node_set.end()){//在headB中找到第一个出现在node_set中的节点时
return headB;
}
headB=headB->next;
}
return NULL;
}
};
int get_list_len(ListNode *head){
int len=0;
while(head){
len++;
head=head->next;
}
return len;
}
ListNode *forward_long_list(int long_len,int short_len,ListNode *head){
int delta = long_len-short_len;
while(head && delta){
head=head->next;
delta--;
}
return head;
}
class Solution2 {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int list_A_len = get_list_len(headA);
int list_B_len = get_list_len(headB);
if(list_A_len>list_B_len){
headA=forward_long_list(list_A_len,list_B_len,headA);
}
else{
headB = forward_long_list(list_B_len,list_A_len,headB);
}
while (headA && headB){
if (headA==headB){
return headA;
}
headA=headA->next;
headB=headB->next;
}
return NULL;
}
};
例3 141.Linked List Cycle
class Solution1{//集合
public:
ListNode *detectCycle(ListNode *head){
std::set<ListNode *> node_set;//设置node_set
while (head){
if (node_set.find(head)!=node_set.end();)
return head;//返回环的第一个节点
node_set.insert(head);
head = head->next;
}
return NULL;
}
};
class Solution{//快慢指针赛跑
public:
ListNode *detectCycle(ListNode *head){
ListNode *fast=head;
ListNode *slow=head;
ListNode *meet=NULL;
while (fast){
slow=slow->next;
fast=fast->next;
if (!fast)
{
return NULL;
}
fast = fast->next;
if (fast==slow)
{
meet=fast;
break;
}
}
if (meet==NULL)
{
return NUll;
}
while (head&&meet)
{
if (head==meet)
{
return head;
}
head=head->next;
meet=meet->next;
}
return NULL;
}
};
例4 86. Partition List
已知链表头指针head与数值x,将所有小于x的节点放在大于或等于的节点前,且保持这些节点的原来的相对位置。
class Solution{//设置俩空头节点
public:
ListNode* partition(ListNode* head,int x){
ListNode less_head(0);
ListNode more_head(0);
ListNode *less_ptr = &less_head;
ListNode *more_ptr = &more_head;
while (head)
{
if(head->val<x){
less_ptr->next=head;
less_ptr=head;
}
else{
more_ptr->next=head;
more_ptr=head;
}
head=head->next;
}
less_ptr->next=more_head.next;
more_ptr->next=NULL;
return less_head.next;
}
};
例5 138.Copy List with Random Pointer
已知一个复杂的链表,节点中有一个指向本链表任意呆个节点的随机指针(也可以为空),求这个链表的深度拷贝。
难点:将随机指针拷贝
map:将某一种数据映射成为另一种数据map<Listnode *,int>
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
class Solution {
public:
Node* copyRandomList(Node* head) {
std::map<Node*,int> node_map;
std::vector<Node*> node_vec;
Node *ptr=head;
int i=0;
while (ptr){
node_vec.push_back(new Node(ptr->label));
node_map[ptr] = i;
ptr=ptr->next;
i++;
}
node_vec.push_back(0);//处理最后一个节点时可以统一操作
ptr=head;
i=0;
while(ptr){
node_vec[i]->next=node_vec[i+1];
if(ptr->random){
int id = node_map[ptr->random];
node_vec[i]->random=node_vec[id];
}
ptr = ptr->next;
i++;
}
return node_vec[0];
}
};
例6 23.Merge k Sorted Lists
合并k有序链表,结果仍为有序链表;
class