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

已知一个复杂的链表,节点中有一个指向本链表任意呆个节点的随机指针(也可以为空),求这个链表的深度拷贝。

难点:将随机指针拷贝image-20220326204058059

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 
posted @ 2022-03-26 21:50  Tim-SaiJun  阅读(166)  评论(0)    收藏  举报