"Prove safety offer" list topic (cow-off 10.23)

Difficulty topic Knowledge Point
03. The resulting list in reverse order vector Recursive, C ++ STL reverse ()
* 14. A linked list node k-th countdown Pointer operations
15. Reverse list The first interpolation method, recursive
16. merge two ordered lists Pointer operations
*** 25. The list of replication complex Deep copy
* A first common junction 36. The two lists of The auxiliary stack, chain stitching, chain interception
*** The ingress node of the linked list 55. The ring Chain scission process, the speed of the pointer
* 56. Delete the list of duplicate nodes Pointer operations

03. The resulting list in reverse order vector

Enter a list, by returning a list sequentially from the tail to the head of ArrayList.

Recursive or positive sequence vector reverse.

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> rst;
        if(head == NULL)return rst;
        rst = printListFromTailToHead(head->next);
        rst.emplace_back(head->val);
        return rst;
    }
};

//----------------------vv---------------------------------
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> rst;
         
        ListNode* pNode = head;
        while(pNode!=NULL){
            rst.emplace_back(pNode->val);
            pNode=pNode->next;
        }
         
        reverse(rst.begin(),rst.end());
        return rst;
    }
};

14. A linked list nodes penultimate k +

Input a linked list, the linked list output reciprocal k-th node.

This question was also asked to interview South, two pointers idea is good, but many of the details involved pointer, easy to write collapse. . .

/*
    首先要判断指针是否为空,以及k是否大于0!!
    然后p1移到最后一个为止,不能指到空
*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if(pListHead == NULL || k==0)
            return NULL;
         
        ListNode* p1=pListHead;
        ListNode* p2=pListHead;
        
        for(int i=1;i<k;i++){
            if(p1->next==NULL){
                return NULL;
            }
            p1=p1->next;
        }
         
        while(p1->next != NULL){
            p1=p1->next;
            p2=p2->next;
        }
         
        return p2;
    }
};

15. Reverse list

The first interpolation method by a new list. Of course, no list is newly opened, it seems positive solutions as well. . Then recursively but also unnecessary.

16. merge two ordered lists

Two monotonically increasing input list and output list after synthesis of two lists, of course, after that we need to meet synthesis list - decreasing the rules.

/*
A:  考归并操作。
T:  要时刻记得指针所指的结点,不要漏掉!
*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        ListNode *newList = new ListNode(0);
        ListNode *p1 = pHead1, *p2 = pHead2, *p3 = newList;
        
        while(p1 && p2){
            if(p1->val <= p2 -> val){
                p3->next = p1;
                p1 = p1->next;
            }else{
                p3->next = p2;
                p2 = p2->next;
            }
            p3 = p3->next;
            p3->next = NULL;
        }
        
        if(p1){
            p3->next = p1;
        }else if(p2){
            p3->next = p2;
        }
        
        return newList->next;
    }
};

25. The complex chain of copy  ++

Title Description

A complex input list (each node has a node value, and two pointers, one pointing to the next node, a special pointer to any other node), returns a value after the head of the list replication complex. (Note that the output results do not return parameter node reference, otherwise the program will return empty sentenced questions directly.

Method 1: map of the old node associated with the new node

Method 2: wonderful ah (funny

img

public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {
        if(pHead==null) return null;
        //1、复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
        RandomListNode p=pHead,newHead=new RandomListNode(0),q;
        while(p!=null){
            RandomListNode newNode =new RandomListNode(p.label);
            newNode.next=p.next;
            p.next=newNode;
            p=newNode.next;
        }

        //2、重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next;
        p=pHead;
        while(p!=null){
            if(p.random!=null)
                p.next.random=p.random.next;
            p=p.next.next;
        }

        //3、拆分链表,将链表拆分为原链表和复制后的链表
        p=pHead;
        q=newHead;
        while(p!=null){
            q.next=p.next;
            p.next=q.next.next;

            p=p.next;
            q=q.next;
        }

        return newHead.next;
    }
}

A first common junction 36. The two lists of the +

Starting from the first common node, it is common node,

Method 1: With the auxiliary stack .

We can list two nodes successively pressed into the two auxiliary stack, such that the two nodes on the tail of the list at the top has two stacks, the stack then compares the two nodes are the same. If so, put the top of the stack continue to pop up the next comparison, the last one until you find the same node. This method is straightforward, time complexity of O (m + n), but using space O (m + n), corresponding to a region with a space for lifting time efficient.

方法 2:将两个链表设置成一样长

具体做法是先求出两个链表各自的长度,然后将长的链表的头砍掉,也就是长的链表先走几步,使得剩余的长度与短链表一样长,这样同时向前遍历便可以得到公共结点。时间复杂度为O(m+n),不需要额外空间。

方法 3:将两个链表拼接起来。

将两个链表进行拼接,一个链表1在前链表2在后,另一个链表2在前链表1在后,则合成的两个链表一样长,然后同时遍历两个链表,就可以找到公共结点,时间复杂度同样为O(m+n)。

//方法3
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {
        ListNode *p1 = pHead1;
        ListNode *p2 = pHead2;
        while(p1!=p2){
            p1 = (p1==NULL ? pHead2 : p1->next);
            p2 = (p2==NULL ? pHead1 : p2->next);
        }
        return p1;
    }
};

55. 链表中环的入口结点+++

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

方法 1:断链法

采用断链法,访问过的节点都断开,最后到达的那个节点一定是循环的入口节点。

public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if (pHead == null || pHead.next == null) {
            return null;
        }
        ListNode fast = pHead.next;
        ListNode slow = pHead;
        while (fast != null) {
            slow.next = null;
            slow = fast;
            fast = fast.next;
        }
        return slow;
    }
}

方法 2:快慢指针

利用快慢指针,快指针一次走两步,慢指针一次走一步,具体思路如下:
①判断是否有环:若链表中存在环,快慢指针一定会在环上某一点相遇(因为相对速度为1);
②确定环的起点:
​ 设x为环前面的路程(黑色路程),a为环入口到相遇点的路程(蓝色路程,假设顺时针走), c为环的长度(蓝色+橙色路程)。则有

  • 慢指针走的路程 Sslow = x + m * c + a
  • 快指针走的路程为Sfast = x + n * c + a
  • 2 Sslow = Sfast

​ 可得 x = c - a,即相遇点后环剩余部分的路程。所以,我们可以让一个指针从链表起点开始走,让一个指针从相遇点开始继续往后走,俩指针会在环的起点相遇。

public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if(pHead==null || pHead.next == null ||pHead.next.next ==null)
            return null;

        // 判环
        ListNode fast= pHead.next.next;
        ListNode slow= pHead.next;

        while (fast!=slow){
            if(fast.next!=null && fast.next.next!=null){
                fast = fast.next.next;
                slow = slow.next;
            } else{
                return null;
            }
        }

        //循环出来的话就是有环,且此时fast==slow,快慢指针在相遇点
        fast=pHead;
        while (fast!=slow){//将在环的起点相遇
            fast=fast.next;
            slow=slow.next;
        }

        return slow;
    }
}

56. 删除链表中重复的结点+

题目描述:

In a sorted linked list, there is a continuous repeating node, delete the duplicate node list, the node does not retain repeated, returns the head pointer list.
For example, the list 1-> 2-> 3-> 3-> 4-> 4-> 5 is treated 1-> 2-> 5

It is easy wrong.

public class Solution {
    public ListNode deleteDuplication(ListNode pHead)
    {
        ListNode newHead = new ListNode(-10000000);//增加头节点统一操作
        newHead.next=pHead;

        ListNode pre = newHead, cur;

        while(pre!=null && pre.next!=null && pre.next.next!=null){
            if(pre.next.val==pre.next.next.val){//pre指向重复元素的前一个元素
                cur=pre.next;
                while(cur.next!=null&&cur.next.val==pre.next.val){
                    cur=cur.next;
                }
                pre.next=cur.next;
            }
            else{// 放在else里是因为刚删完元素后,不能保证pre指针后面两个元素不等,所以pre要保持不动
                pre = pre.next;
            }
        }

        return newHead.next;
    }
}

Guess you like

Origin www.cnblogs.com/weseewe/p/11729919.html