第二章 链表part02

64 阅读4分钟

第二章 链表* part02*

24. 两两交换链表中的节点

题目链接 : leetcode.cn/problems/sw…

Code

/**
 * 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* swapPairs(ListNode* head) {
​
        // (相对)“ 核心 区”
​
        
​
​
        if(head == NULL)            // 分 情况     /   划分 情况 
        {
            return NULL;
​
        }else
        if(head->next == NULL)
        {
            return head;
​
        }else
        if(head->next != NULL)
        {
            ListNode* spear = head->next->next;
            ListNode* p = head;
​
            //cout<<"head->val : "<<head->val<<endl;
            //cout<<"head->next ->val : "<<head->next ->val<<endl;
​
            ListNode* pre ;
​
            //**   pre 处理 位   ,  没有 更 靠 前 的 了
​
            pre = p ;
​
            p->next ->next = p ;
​
            head = p->next;
​
            p->next = spear ;
​
            p = spear ;
​
            
​
            // 注意 不要 忘了 更新  头结点 
​
        
​
            do
            {
                
                if(p == NULL)
                {
                    return head;
​
                // swapPairs 链表 处理 将要 结束 
                }else
                if(p->next == NULL)
                {
                    return head;
                }else
                if(p->next != NULL)
                {
                    spear = p->next->next;
                    pre->next = p->next;
​
                    pre = p;
​
                    p->next ->next = p;
​
                    p->next = spear;
​
                    p = spear ;               // 注意 不要 忘了 更新  " p "
​
​
                }
​
            }while(p != NULL );
​
​
            return head;
​
​
        }
​
        return NULL;                //return head;
​
    }
};

19.删除链表的倒数第 N 个结点

题目链接 : leetcode.cn/problems/re…

/**
 * 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)
        {
            return NULL;
​
        }else
        if(head->next == NULL)
        {
            if(n != 1)
            {
                //      cout<<"Error At removeNthFromEnd  Parameter   " n "  " << endl ;
​
                return NULL ;
            }
            else
            {
                return NULL ;
​
            }
​
        }
        else
        {
            ListNode* spear = head ;
            ListNode* p = head ;
​
            ListNode* pre = NULL ;     //  注意 对 指针  进行  初始化   以   提升  稳定性  ;
​
            //if(pre != NULL)
            //{
            //    cout<<"pre != NULL"<<endl;
            //
            //}
​
            int i = 0 ;
​
            for( ;i < n; i++)
            {
                                        //if(spear == NULL)     cout<<"Error At removeNthFromEnd  Parameter   " n "  "
                
                spear = spear->next;
​
            }
​
            /*
            if(spear == NULL)           // “ 伞 ” 没 拽 开 时  的  操作
            {                           // "pre"
                head = p -> next ;
​
            }
            */
​
            //cout<<111111111111<<endl;
​
​
            while(spear != NULL)            // 这里 的 代码 很有可能 被 优化 了
            {
                pre = p ;          
                p = p -> next ;
                spear = spear -> next ;
​
            }
​
​
            
            //cout<<"pre : "<<pre<<endl ;
            
            if(pre == NULL)
            {
                //cout<<22222222<<endl;          
                head = p -> next ;
​
                //  如果  pre  没有 被 拽 开
​
            }
            else
            {
                ////ListNode * temp = p -> next ;           // 注意  空 指针
​
                //if(temp == NULL)
                //{
                //    cout<<"temp == NULL"<<endl;
                //
                //}
​
                ////pre->next = temp;
​
                pre->next = p -> next ;
​
            }
​
​
            
​
​
            return head ;
​
        }
​
​
        
​
​
​
​
    }
};

面试题 02.07. 链表相交

题目链接 : leetcode.cn/problems/in…

Code (基础解 / 暴力解 )

/**
 * 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) {
        vector<ListNode *> numsA;
        vector<ListNode *> numsB;
​
        ListNode * pA = headA;
        ListNode * pB = headB;          // 练习    ,     过载  上升  
​
        //int Index_Find = 
​
        ListNode * ptr_Find = NULL ;
​
        int Find = 0;
​
​
        while(pA != NULL)
        {
            numsA.push_back(pA);
            pA = pA -> next ;
        }
​
        while(pB != NULL)
        {
            numsB.push_back(pB);
            pB = pB -> next ;
        }
​
        int i = 0 ;
​
        int lenA = numsA.size();
​
        int j = 0 ;
​
        int lenB = numsB.size();
​
        for( ;i < lenA ; i++)
        {
            //cout<<"i = "<<i<<endl;
            //cout<<"ptr = "<<numsA[i]<<endl;
​
            j = 0 ;                     // 注意 对 j 进行 刷新
​
            for( ;j < lenB ; j++)
            {
                //cout<<"j = "<<j<<endl;
                //cout<<"ptr = "<<numsB[j]<<endl;
​
                if(numsA[i] == numsB[j])
                {
                    ptr_Find = numsA[i];
​
                    Find = 1;
                    //cout<<"Find "<<endl;
​
                    break;
​
                }
​
                if(Find == 1)
                {
                    break ;
​
                }
​
​
            }
​
​
        }
​
​
        return ptr_Find ;
​
        
    }
};

“ 双 指针 ” 步伐 协调 解 (一周目 和 二周目)

时间 复杂度 :O(n) 空间 复杂度 : O(1)

Code :

/**
 * 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) {
        vector<ListNode *> numsA;
        vector<ListNode *> numsB;
​
        ListNode * p1 = headA;
        ListNode * p2 = headB;          // 练习    ,     过载  上升  
​
        //int Index_Find = 
​
        ListNode * ptr_Find = NULL ;
​
        int Find = 0;
​
        int count = 1;
​
        int Find_1_Round = 1;
​
        int Find_2_Round = 1;
​
​
        //  步伐  协同  型   Test
​
        while( (Find_1_Round < 3 && Find_2_Round < 3 ) )
        {
            if(Find_1_Round < 3 && Find_2_Round >= 3)
            {
                cout<<"Error At getIntersectionNode Asynchronous"<<endl;
            }
​
            if(Find_1_Round >= 3 && Find_2_Round < 3)
            {
                cout<<"Error At getIntersectionNode Asynchronous"<<endl;
            }
​
            if(p1 == p2)
            {
                return p1;
            }
​
            //cout<<"Find_1_Round = "<<Find_1_Round<<endl;
            //cout<<"Find_2_Round = "<<Find_2_Round<<endl;
            //cout<<"count = "<<count<<endl;
​
​
            //if(p1 != NULL)
            //{
                //cout<<"p1->val = "<<p1->val<<endl;
            //}
​
            //if(p2 != NULL)
            //{
                //cout<<"p2->val = "<<p2->val<<endl;
            //
            //}
​
            count++;
​
​
            
            
            if(Find_1_Round == 1)
            {
                if(p1 == NULL)
                {
                    Find_1_Round += 1;
                    p1 = headB;
                }
                else
                {
                    p1 = p1 -> next ;
                }
​
                
                
            }else
            if(Find_1_Round == 2)
            {
                if(p1 == NULL)
                {
                    Find_1_Round += 1;
                    //p1 = headA;
                }
                else
                {
                    p1 = p1 -> next ;
                }
​
                
​
                
​
            }
​
​
            if(Find_2_Round == 1)
            {
                if(p2 == NULL)
                {
                    Find_2_Round += 1;
                    p2 = headA;             //  注意  复制 并 修改 时  很有  可能  产生 错误
                }                                   //  注意 做好 区间 划分
                else{
                    p2 = p2 -> next ;
                }
​
                
                
            }else
            if(Find_2_Round == 2)
            {
                if(p2 == NULL)
                {
                    Find_2_Round += 1;
                    //p1 = headB;
                }
                else{
                    p2 = p2 -> next ;
​
                }
​
                
​
                
            }
​
​
            //cout<<"New  Find_1_Round = "<<Find_1_Round<<endl;
            //cout<<"New  Find_2_Round = "<<Find_2_Round<<endl;
​
            //cout<<endl;
​
​
        }
​
​
        return NULL ;
​
​
​
        
    }
};

142.环形链表 II

题目链接 : leetcode.cn/problems/li…

Code :

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
​
                        // road
​
                        // 领先 步数        (环 外 长度)
​
                        // xx 补集
​
                        // xx 点 的 移动    2 * 补集 
​
                        // 配合 之前 一个   领先 步数 
​
                        //还 多出  1 * 补集 
​
                        // 配合 一个 领先 步数 得出
​
        ListNode * p1 = head;
        ListNode * p2 = head;
​
        int count_1 = 0;
        int count_2 = 0;
​
        int Find_Cycle = 0;
​
​
​
        while((p1 != NULL )&&(p1->next != NULL) && p2 != NULL)
        {
            
            p1 = p1 -> next;
            p1 = p1 -> next;
​
            count_1 += 2 ;
​
            p2 = p2 -> next;
​
            count_2 += 1 ;
​
            if(p1 == p2)
            {
                Find_Cycle = 1;
​
                break;
            }
​
                // Logic :    count_1 - count_2 = (环 长度)
​
                // p1 的 绝对 位置  在 相对于 环 起点  (领先 步数) 补集 的 位置
​
                // 回到 环 起点  需要  (之前 的 一开始 的  领先 步数)
​
    
            
        }
​
        if(Find_Cycle == 1)
        {
            ListNode * p3 = head;
​
            do
            {
                if(p1 == p3)
                {
                    return p1;
                }
​
                p3 = p3 -> next;
                p1 = p1 -> next;
​
            }while(1);
        }
        else
        {
            return NULL;
        }
​
​
        
    }
};