zoukankan      html  css  js  c++  java
  • 链表题目汇总

    经典题目参考:

    https://blog.csdn.net/walkinginthewind/article/details/7393134

     

    167. 链表求和

    你有两个用链表代表的整数,其中每个节点包含一个数字。数字存储按照在原来整数中相反的顺序,使得第一个数字位于链表的开头。写出一个函数将两个整数相加,用链表形式返回和。

    样例

    样例 1:

    输入: 7->1->6->null, 5->9->2->null
    输出: 2->1->9->null	
    样例解释: 617 + 295 = 912, 912 转换成链表:  2->1->9->null
    

    样例 2:

    输入:  3->1->5->null, 5->9->2->null
    输出: 8->0->8->null	
    样例解释: 513 + 295 = 808, 808 转换成链表: 8->0->8->null


    对题目理解不好,数据类型换成long 解答:通过70%

    class Solution {
    public:
    /**
    * @param l1: the first list
    * @param l2: the second list
    * @return: the sum list of l1 and l2 
    */
    ListNode * addLists(ListNode * l1, ListNode * l2) {
    // write your code here
    stack<int> res1,res2;
    
    if(l1==NULL ){
    return l2;
    }
    
    if(l2==NULL){
    return l1;
    }
    
    while(l1!=NULL){
    
    res1.push(l1->val);
    l1=l1->next;
    
    }
    
    while(l2!=NULL){
    
    res2.push(l2->val);
    l2=l2->next;
    }
    
    int len1=res1.size();
    int len2=res2.size();
    
    int num1 = 0;
    while(len1--){
    int temp1=res1.top()*pow(10,len1);
    res1.pop();
    
    num1 = num1+temp1;
    
    }
    
    int num2 = 0;
    while(len2--){
    int temp2=res2.top()*pow(10,len2);
    res2.pop();
    
    num2 = num2+temp2;
    
    }
    
    int num = num1+num2;
    
    
    cout<<num<<endl;
    vector<int> result;
    
    while(num>=10){
    int temp = num%10;
    result.push_back(temp);
    
    num=num/10;
    
    }
    
    result.push_back(num);
    
    int l = result.size();
    cout<<l<<endl;
    
    ListNode* head = new ListNode(result[0]);
    
    ListNode * temp =head;
    for(int i=1;i<l;i++){
    
    ListNode* node = new ListNode(result[i]);
    cout<<node->val<<endl;
    temp->next=node;
    temp = node;
    }
    
     
    
    return head;
    
    }
    };
    

      

    优秀解法:

    /**
     * Definition of singly-linked-list:
     * class ListNode {
     * public:
     *     int val;
     *     ListNode *next;
     *     ListNode(int val) {
     *        this->val = val;
     *        this->next = NULL;
     *     }
     * }
     */
    
    class Solution {
    public:
        /**
        * @param l1: the first list
        * @param l2: the second list
        * @return: the sum list of l1 and l2
        */
        ListNode *addLists(ListNode *l1, ListNode *l2) {
            // write your code here
            ListNode *head = new ListNode(0);
            ListNode *end = head;
            ListNode *curr1 = l1;
            ListNode *curr2 = l2;
            int carry = 0;
            // 深入理解题目,求和进位进到后面去了,所以从前往后遍历就行
            while (curr1 != nullptr || curr2 != nullptr || carry != 0)
            {
                int a1 = 0;
                int a2 = 0;
                if (curr1 != nullptr)
                {
                    a1 = curr1->val;
                    curr1 = curr1->next;
                }
                if (curr2 != nullptr)
                {
                    a2 = curr2->val;
                    curr2 = curr2->next;
                }
                int sum = a1 + a2 + carry;
                carry = sum / 10;
                sum %= 10;
                ListNode *curr = new ListNode(sum);
                end->next = curr;
                end = curr;
            }
            return head->next;
        }
    };
    

      

    165. 合并两个排序链表

    将两个排序链表合并为一个新的排序链表

    样例

    样例 1:
    	输入: list1 = null, list2 = 0->3->3->null
    	输出: 0->3->3->null
    
    
    样例2:
    	输入:  list1 =  1->3->8->11->15->null, list2 = 2->null
    	输出: 1->2->3->8->11->15->null
    /**
     * Definition of singly-linked-list:
     * class ListNode {
     * public:
     *     int val;
     *     ListNode *next;
     *     ListNode(int val) {
     *        this->val = val;
     *        this->next = NULL;
     *     }
     * }
     */
    
    class Solution {
    public:
        /**
         * @param l1: ListNode l1 is the head of the linked list
         * @param l2: ListNode l2 is the head of the linked list
         * @return: ListNode head of linked list
         */
        ListNode * mergeTwoLists(ListNode * l1, ListNode * l2) {
            // write your code here
            
            if(l1 ==NULL){
                return l2;
            }
            
            if(l2== NULL){
                return l1;
            }
            
            ListNode * head= NULL;
            
            
            if(l1->val >= l2->val){
                head=l2;
                head->next = mergeTwoLists(l1,l2->next);
            }
            else{
                head=l1;
                head->next = mergeTwoLists(l1->next,l2);
            }
            
            return head;
            
            
        }
    };
    

      

    翻转链表:

    /**
     * Definition of singly-linked-list:
     *
     * class ListNode {
     * public:
     *     int val;
     *     ListNode *next;
     *     ListNode(int val) {
     *        this->val = val;
     *        this->next = NULL;
     *     }
     * }
     */
    
    class Solution {
    public:
        /**
         * @param head: n
         * @return: The new head of reversed linked list.
         */
        ListNode * reverse(ListNode * head) {
            // write your code here
    
            if(head == NULL || head->next == NULL){
            	return head;
            }
    
            ListNode * head_new = NULL;
            ListNode * cur = head;
    
            while(cur!=NULL){
            	ListNode * temp = cur;
            	cur = cur->next;
    
            	ListNode * head_pre= head_new;
    
            	head_new =temp;
    
            	head_new->next = head_pre;
            	head_new->val=temp->val;
    
            }
    
            return head_new;
    
        }
    };
    

      

    // 找到单链表倒数第n个节点,保证链表中节点的最少数量为n。

    // 样例
    // Example 1:
    // Input: list = 3->2->1->5->null, n = 2
    // Output: 1

    // 当语言有问题时,可以重置一下



    class Solution {
    public:
        /*
         * @param head: The first node of linked list.
         * @param n: An integer
         * @return: Nth to last node of a singly linked list. 
         */
        ListNode * nthToLast(ListNode * head, int n) {
            // write your code here
            // 双指针问题解决
            if(head==NULL || n<=0 ){
            	return NULL;
            }
    
            ListNode *fast=head;
            ListNode *slow=head;
    
            while(n--){
            	fast = fast->next;
            }
    
            while(fast!=NULL){
            	fast = fast->next;
            	slow = slow->next;
            }
            
            return slow;
        }
    };
    

      

    102. 带环链表

    给定一个链表,判断它是否有环。

    样例

    ```
    样例 1:
    	输入: 21->10->4->5,  then tail connects to node index 1(value 10).
    	输出: true
    	
    样例 2:
    	输入: 21->10->4->5->null
    	输出: false
    
    ```
    

    挑战

    不要使用额外的空间

    /**
     * Definition of singly-linked-list:
     * class ListNode {
     * public:
     *     int val;
     *     ListNode *next;
     *     ListNode(int val) {
     *        this->val = val;
     *        this->next = NULL;
     *     }
     * }
     */
    
    
    class Solution {
    public:
        /**
         * @param head: The first node of linked list.
         * @return: True if it has a cycle, or false
         */
        bool hasCycle(ListNode * head) {
            // write your code here
            if(head==NULL || head->next==NULL){
            	return false;
            }
    
            ListNode* slow = head;
            ListNode* fast = head;
            
            // 注意,这里要避免野指针出现,判断快指针是否到头即可
            while(fast !=NULL && fast->next !=NULL){
            	slow = slow->next;
            	fast = fast->next->next;
            	if(slow == fast){
            		return true;
            	}
    
            }
    
            return false;
    
        }
    };
    

      

    给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二叉搜索树

    样例

    样例 1:
    	输入: array = 1->2->3
    	输出:
    		 2  
    		/ 
    		1  3
    		
    样例 2:
    	输入: 2->3->6->7
    	输出:
    		 3
    		/ 
    	       2   6
    		     
    		      7
    
    	解释:
    	可能会有多个符合要求的结果,返回任意一个即可。
    /**
     * Definition of ListNode
     * class ListNode {
     * public:
     *     int val;
     *     ListNode *next;
     *     ListNode(int val) {
     *         this->val = val;
     *         this->next = NULL;
     *     }
     * }
     * Definition of TreeNode:
     * class TreeNode {
     * public:
     *     int val;
     *     TreeNode *left, *right;
     *     TreeNode(int val) {
     *         this->val = val;
     *         this->left = this->right = NULL;
     *     }
     * }
     */
    
    
    // class Solution {
    // public:
    //     /*
    //      * @param head: The first node of linked list.
    //      * @return: a tree node
    //      */
    //     TreeNode * sortedListToBST(ListNode * head) {
    //         // write your code here
    
    //         if(head==NULL){
    //         	return NULL;
    //         }
    
    //         if(head->next==NULL){
    //         	TreeNode* t_node=new TreeNode(head->val);
    //         	return t_node;
    //         }
    
    
    //         if(head->next->next==NULL){
    //         	TreeNode* t_node=new TreeNode(head->val);
    //         	t_node->right = new TreeNode(head->next->val);
    //         	return t_node;
    //         }
    
    
    //         int len = 0;
    //         ListNode * temp = head;
    //         while(temp){
    //         	len++;
    //         	temp = temp->next;
    //         }
    
    //         int mid = len/2;
    
    //         ListNode * mid_node = head;
    //         while(mid--){
    //         	mid_node = mid_node->next;
    //         }
    
    //         ListNode * mid_next = mid_node->next;
    //         mid_node->next == NULL;
    
    //         TreeNode* root = new TreeNode(mid_node->val);
            
    //         root->left = sortedListToBST(head);
    //         root->right = sortedListToBST(mid_next);
    
    
    //         return root;
    
    
    //     }
    // };
    
    
    
    class Solution {
    public:
        TreeNode* sortedListToBST(ListNode* head) {
            vector<int> v;
            ListNode* cur=head;
            while(cur!=NULL){
                v.push_back(cur->val);
                cur=cur->next;
            }
            TreeNode* root=buildBST(v,0,v.size()-1);
            return root;
        }
        TreeNode* buildBST(vector<int>& nums,int l,int r){
           if(l>r)  return NULL;
            int mid=(l+r)/2;
            auto node= new TreeNode(nums[mid]);
            node->left=buildBST(nums,l,mid-1);
            node->right=buildBST(nums,mid+1,r);
            return node;
        }
    };
    

      

    剑指 Offer 52. 两个链表的第一个公共节点

    输入两个链表,找出它们的第一个公共节点。

    如下面的两个链表:

    在节点 c1 开始相交。

    示例 1:

    输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
    输出:Reference of the node with value = 8
    输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
            if(headA==NULL || headB==NULL){
                return NULL;
            }
    
            ListNode *A = headA;
            int lenA=0;
            ListNode *B = headB;
            int lenB=0;
    
            while(A!=NULL){
                lenA++;
                A=A->next;
            }
            while(B!=NULL){
                lenB++;
                B=B->next;
            }
            int step= 0;
            ListNode *tempA=headA;
            ListNode *tempB=headB;
            if(lenA>lenB){
                step= lenA-lenB;
                while(step){
                    tempA=tempA->next;
                    step--;
                }
                while(tempA!=NULL&&tempB!=NULL){
                    if(tempA==tempB){
                        return tempA;
                    }
                    tempA=tempA->next;
                    tempB=tempB->next;
                }
    
            }else{
                step= lenB-lenA;
                while(step){
                    tempB=tempB->next;
                    step--;
                }
    
                while(tempA!=NULL&&tempB!=NULL){
                    if(tempA==tempB){
                        return tempA;
                    }
                    tempA=tempA->next;
                    tempB=tempB->next;
                }
    
    
            }
    
            return NULL;
    
    
    
    
    
        }
    };
    

      

    思路:快慢指针

    遍历两个链表,然后计算两个链表的节点数量,计算两个链表的节点数量差;

    然后重新开始遍历,节点多的链表先开始,走多出来的节点个步数,然后节点少的链表和节点多的链表同时开始遍历,当指向的位置相同时,即为第一个交点;

    给你一个链表数组,每个链表都已经按升序排列。

    请你将所有链表合并到一个升序链表中,返回合并后的链表。

    示例 1:

    输入:lists = [[1,4,5],[1,3,4],[2,6]]
    输出:[1,1,2,3,4,4,5,6]
    解释:链表数组如下:
    [
      1->4->5,
      1->3->4,
      2->6
    ]
    将它们合并到一个有序链表中得到。
    1->1->2->3->4->4->5->6
    

    示例 2:

    输入:lists = []
    输出:[]
    

    示例 3:

    输入:lists = [[]]
    输出:[]
    

    提示:

    • k == lists.length
    • 0 <= k <= 10^4
    • 0 <= lists[i].length <= 500
    • -10^4 <= lists[i][j] <= 10^4
    • lists[i] 按 升序 排列
    • lists[i].length 的总和不超过 10^4

    两种思路:

    1)使用优先队列的方法,每个链表取一个元素放入优先队列,每次从优先队列里取最小的那个元素

    2)归并排序的思想,有序链表两两合并

    https://blog.csdn.net/aikudexue/article/details/90769813

    class Solution {
    public:
        ListNode* mergeKLists(vector<ListNode*>& lists) {
            priority_queue<ListNode*, vector<ListNode*>, compare> q;
            for (auto l : lists) {
                if (l) {
                    q.push(l);  //每个链表取一个元素放入优先队列
                }
            }
            
            ListNode pre(0);  //新建一个头结点,可以防止丢失最终链表的头
            ListNode *node = &pre
            while (q.size()) {
                ListNode *top = q.top();  //从优先队列里取最小的那个元素
                q.pop();
                node->next = top;  //将弹出的那个元素连到最终链表上
                node = node->next;  //指针向后移一步
                if (top->next) {
                    q.push(top->next); //将下一个元素入队列
                }
            }
            return pre.next;
        }
        
        struct compare {
            bool operator()(const ListNode* l1, const ListNode* l2) {
                return l1->val > l2->val;
            }
        };
    };
    

      

      

      

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    // class Solution {
    // public:
    //     ListNode* mergeKLists(vector<ListNode*>& lists) {
    //         priority_queue<ListNode*, vector<ListNode*>, compare> q;
    //         for (auto l : lists) {
    //             if (l) {
    //                 q.push(l);  //每个链表取一个元素放入优先队列
    //             }
    //         }
            
    //         ListNode pre(0);  //新建一个头结点,可以防止丢失最终链表的头
    //         ListNode *node = ⪯
    //         while (q.size()) {
    //             ListNode *top = q.top();  //从优先队列里取最小的那个元素
    //             q.pop();
    //             node->next = top;  //将弹出的那个元素连到最终链表上
    //             node = node->next;  //指针向后移一步
    //             if (top->next) {
    //                 q.push(top->next); //将下一个元素入队列
    //             }
    //         }
    //         return pre.next;
    //     }
        
    //     struct compare {
    //         bool operator()(const ListNode* l1, const ListNode* l2) {
    //             return l1->val > l2->val;
    //         }
    //     };
    // };
    
    class Solution {
    public:
        ListNode* mergeKLists(vector<ListNode*>& lists) {
            return partition(lists, 0, lists.size()-1); //合并0-(size-1)的链表
        }
        
        ListNode* partition(vector<ListNode*>& lists, int start, int end){
            if(start == end){
                return lists[start];
            }
            
            if(start < end){
                int mid = (end+start)/2;
                
                ListNode* l1 = partition(lists, start, mid);  //合并start->mid的链表
                ListNode* l2 = partition(lists, mid+1, end);  //合并mid+1到end的链表
                //partition最终递归到最后还是两个链表的合并.举个例子来说比如合并6个链表,那么按照分治法,我们首先分别合并1和4,2和5,3和6。这样下一次只需合并3个链表,我们再合并1和3,最后和2合并就可以了。
                return merge(l1, l2); 
            }
            
            return NULL;
        }
        
        ListNode* merge(ListNode* l1, ListNode* l2){  //合并L1,L2两个有序链表
            if(!l1) return l2;
            if(!l2) return l1;
            
            if(l1->val < l2->val){
                l1->next = merge(l1->next, l2);
                return l1;
            }else{
                l2->next = merge(l1, l2->next);
                return l2;
            }
        }
    };
    

      

    重新写的思路:
    1)先合并两个

    2)然后两两合并

    class Solution {
    public:
         ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
            ListNode *newHead=new ListNode(0);
            ListNode *head=newHead;
     
               while(l1!=NULL&&l2!=NULL){
                    if(l1->val>l2->val){
                        newHead->next=l2;
                        l2=l2->next;
                        newHead=newHead->next;
                    }else{
                        newHead->next=l1;
                        l1=l1->next;
                        newHead=newHead->next;
                    }
                    
                }
                if(l1!=NULL&&l2==NULL){
                    newHead->next=l1;
                    
                }else if(l1==NULL&&l2!=NULL){
                    newHead->next=l2;
                }
            
            return head->next;
            }
     
        ListNode* mergeKLists(vector<ListNode*>& lists) {
            if(lists.size()==0){
                return NULL;
            }
    
    		int interval =1;
    		int len = lists.size();
    
    		while(interval<len){
    			for(int i=0;i<len-interval;){
    				lists[i]=mergeTwoLists(lists[i],lists[i+1]);
    				i=i+interval*2;
    			}
    			interval = interval*2;
    		}
    
    		return lists[0];
        }
    };
    

      

    19. 删除链表的倒数第N个节点
    给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

    示例:

    给定一个链表: 1->2->3->4->5, 和 n = 2.

    当删除了倒数第二个节点后,链表变为 1->2->3->5.
    说明:

    给定的 n 保证是有效的。

    进阶:

    你能尝试使用一趟扫描实现吗?


    思路:快慢指针实现,但需要注意链表中删除头节点的情况特殊处理;

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
    
            // 双指针问题解决
            if(head==NULL || n<=0 ){
                return NULL;
            }
    
            if(head->next==NULL){
                return NULL;
            }
    
            ListNode *fast=head;
            ListNode *slow=head;
     
            while(n--){
                fast = fast->next;
            }
    
            ListNode * temp = NULL;
    
            while(fast!=NULL){
                fast = fast->next;
                temp = slow;
                slow = slow->next;
            }
            if(slow==head){
                ListNode * head_new = slow->next;
                slow->next = NULL;
                return head_new;
            }
            else{
                temp->next= slow->next;
                slow->next=NULL;
            }
    
            return head;
    
        }
    };
    

      

    83. 删除排序链表中的重复元素
    给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

    示例 1:

    输入: 1->1->2
    输出: 1->2
    示例 2:

    输入: 1->1->2->3->3
    输出: 1->2->3

    思路:很简单,遍历链表,因为链表有序,依次比较当前元素和下一个元素是否相等,相等则删除下一个元素,将链表指针重新指向;
    递归这个过程,直到链表结束,一次AC

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* deleteDuplicates(ListNode* head) {
            if(head==NULL||head->next==NULL){
                return head;
            }
    
            ListNode* cur = head;
    
            while(cur->next!=NULL){
                if(cur->val==cur->next->val){
                    cur->next=cur->next->next;
                    deleteDuplicates(head);
                }
                else{
                    cur=cur->next;
                }
            }
    
            return head;
        }
    };
    

      

    61. 旋转链表
    给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。

    示例 1:

    输入: 1->2->3->4->5->NULL, k = 2
    输出: 4->5->1->2->3->NULL
    解释:
    向右旋转 1 步: 5->1->2->3->4->NULL
    向右旋转 2 步: 4->5->1->2->3->NULL
    示例 2:

    输入: 0->1->2->NULL, k = 4
    输出: 2->0->1->NULL
    解释:
    向右旋转 1 步: 2->0->1->NULL
    向右旋转 2 步: 1->2->0->NULL
    向右旋转 3 步: 0->1->2->NULL
    向右旋转 4 步: 2->0->1->NULL


    解题思路:
    step1:将链表首位相连成环;
    step2:在k = list_len - k % list_len处断开。

    如果理解起来比较抽象,可以画个图帮助理解,找到断开点以及返回新的头节点;
    注意链表遍历cur和cur2不要用错,--k 还是 k--要验证清楚

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    
    class Solution {
    public:
        ListNode* rotateRight(ListNode* head, int k) {
            
            if(head==NULL){
                return head;
            }
            
            ListNode* cur = head;
            ListNode* cur2 = head;
            int len = 1;
            while(cur->next!=NULL){
                cur= cur->next;
                len++;
            }
            
            cur->next = head;
            
            k = len-k%len;
            while(--k){
                cur2=cur2->next;
            }
            ListNode* head_new = cur2->next;
            cur2->next=NULL;
            
            return head_new;
            
        }
    };
    

      

    思路参考:https://blog.csdn.net/starzyh/article/details/90345257

    138. 复制带随机指针的链表
    给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

    要求返回这个链表的 深拷贝。

    我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

    val:一个表示 Node.val 的整数。
    random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。

    思路:
    第一次遍历链表的时候,复制旧链表的节点值建立一个新的链表,同时定义一个 unordered_map 作为哈希表,哈希表的键为旧链表的节点指针,值为新链表的节点指针。

    然后,第二次遍历链表,访问旧链表节点的随机指针,然后以此为键从 map 中取出对应的新链表节点指针,这也就是当前新链表节点的随机指针。

    https://www.cnblogs.com/seniusen/p/10142869.html

    /*
    // Definition for a Node.
    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) {
            
            unordered_map<Node *, Node *> nodemap;
            Node *temp = head;
            Node *new_head = new Node(0); //哨兵节点,方便操作
            Node *copy_temp = new_head;
     
            // 建立新链表
            while (temp)
            {
                copy_temp->next = new Node(temp->val);
                nodemap[temp] = copy_temp->next;
                
                temp = temp->next;
                copy_temp = copy_temp->next;
            }
            
            Node *random_temp = NULL;
            temp = head;
            copy_temp = new_head->next;
            // 填充新链表的随机指针
            while (temp)
            {
                random_temp = temp->random;
                if (random_temp != NULL)   copy_temp->random = nodemap[random_temp];
                else    
                    copy_temp->random = NULL;
                
                temp = temp->next;
                copy_temp = copy_temp->next;
            }
            
            return new_head->next;
        }
    };
    

      

    876. 链表的中间结点
    给定一个头结点为 head 的非空单链表,返回链表的中间结点。
    如果有两个中间结点,则返回第二个中间结点。

    示例 1:

    输入:[1,2,3,4,5]
    输出:此列表中的结点 3 (序列化形式:[3,4,5])
    返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
    注意,我们返回了一个 ListNode 类型的对象 ans,这样:
    ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
    示例 2:

    输入:[1,2,3,4,5,6]
    输出:此列表中的结点 4 (序列化形式:[4,5,6])
    由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。


    思路:快慢指针,注意奇数个节点和偶数个节点,设置一个标志未来处理
    1--2--3--4--5
    1--2--3--4

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* middleNode(ListNode* head) {
            if(head ->next == NULL){
                return head;
            }
            if(head->next->next==NULL){
                return head->next;
            }
    
            ListNode* slow = head;
            ListNode* fast =head;
    
            int flag =1;
            while(fast->next!=NULL&&fast->next->next!=NULL){
                fast = fast->next->next;
                slow = slow->next;
            }
    
            if(fast->next!=NULL){
                flag=0;
            }
    
            if(flag==0){
                return slow->next;
            }
    
            return slow;
    
        }
    };
    

      




     
  • 相关阅读:
    pip错误:'utf-8' codec can't decode byte解决方法
    windows中python2与python3共存
    Alpha 冲刺 (3/10)
    Alpha 冲刺 (2/10)
    Alpha 冲刺 (1/10)
    项目需求分析报告答辩总结
    项目选题报告答辩总结
    项目UML设计(团队)
    # 第七次作业--项目需求分析(团队)
    结对项目--第二次作业
  • 原文地址:https://www.cnblogs.com/Allen-rg/p/13647724.html
Copyright © 2011-2022 走看看