Some leetcode questions of the linked list+python(c++)

The following knowledge points are mainly common: 

1-1. Please write a function to delete a given (non-end) node in a linked list, and you will only be given the required node to be deleted.

python:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteNode(self, node):
        """
        :type node: ListNode
        :rtype: void Do not return anything, modify node in-place instead.
        """
        node.val = node.next.val
        node.next = node.next.next

C++ implementation:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) {
        node->val = node->next->val;
        node->next = node->next->next;
    }
};

1-2 . Delete duplicate elements in the sorted linked list

Determine whether it is a duplicate node by comparing the value of a node with the nodes after it. If it is a duplicate, we change the next pointer of the current node so that it skips the next node and points directly to the node after the next node. If it is not a duplicate, the node moves down.

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        node = head
        while node and node.next:
            if node.val == node.next.val:
                node.next = node.next.next
            else:
                node = node.next
        return head

C++ implementation:

/**
 * 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* deleteDuplicates(ListNode* head) {
        ListNode* node = head;
        while(node !=nullptr && node->next !=nullptr){
            if(node->val == node->next->val){
                node->next = node->next->next;
            }
            else
            {
                node = node->next;
            }
        }
        return head;
    }
};

1-3 . Delete the Nth node from the bottom of the linked list

Idea: Find the length of the linked list, find the previous node of the node to be deleted by adding a node to the head node, and then delete it

Method 1: Loop

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        length = 0 
        node = head
        #获取链表长度
        while node:
            length+=1
            node= node.next
        # print(length)

        curr_length = 0
        new_head = ListNode(0)
        new_head.next = head
        node2=new_head
        stop_length = length - n
        #循环走到要删除节点的前一个节点
        while stop_length:
            stop_length-=1
            node2 = node2.next
        #跳过要删除的节点即可
        node2.next = node2.next.next
        return new_head.next

Method 2: Recursion

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def __init__(self):
        self.count = 0
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        if not head:            
            return head  
        
        head.next = self.removeNthFromEnd(head.next, n) # 递归调用
        self.count += 1 # 回溯时进行节点计数
        return head.next if self.count == n else head 

Method 3: double pointer

The fist pointer and the second pointer are separated by n, so that first runs to the end, and the next node of second is the last nth

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    # def __init__(self):
    #     self.count = 0
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        new_head =  ListNode(0)
        new_head.next = head
        first  = head
        second = new_head
        for i in range(n):
            first = first.next
        while first:
            first = first.next
            second = second.next
        second.next = second.next.next
        return new_head.next

C++ implementation: 

/**
 * 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) {
        ListNode* new_head = new ListNode(0);
        new_head ->next = head;
        ListNode* first = head;
        ListNode* second = new_head;
        for(int i=0;i<n;i++){
            first = first->next;
        }
        while(first){
            first = first->next;
            second = second->next;
        }
        second->next = second->next->next;
        return new_head->next;
    }
};

1-4 . Delete the node of the linked list

Idea: double pointer

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteNode(self, head: ListNode, val: int) -> ListNode:
        if head is None:
            return head
        new_head = ListNode(0)
        new_head.next = head
        pre = new_head
        cur = head
        while cur.val != val:
            pre = cur
            cur = cur.next
        pre.next = cur.next
        return new_head.next

C++ implementation:

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

1-5. Swap nodes in the linked list in pairs

Idea: iterative method

python code: 

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        new_head = ListNode(0)
        new_head.next = head
        temp = new_head
        while temp.next and temp.next.next:
            node1 = temp.next
            node2 = temp.next.next
            temp.next = node2
            node1.next = node2.next
            node2.next = node1
            temp = node1
        return new_head.next

C++ implementation:

/**
 * 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) {
        ListNode* new_head = new ListNode(0);
        new_head->next = head;
        ListNode* temp = new_head;
        while(temp->next && temp->next->next){
            ListNode* head1 = temp->next;
            ListNode* head2 = temp->next->next;
            temp->next = head2;
            head1->next = head2->next;
            head2->next = head1;
            temp = head1;
        }
        return new_head->next;
    }
};

2-1 . Reverse linked list

Idea 1: Double pointer 

 

class Solution(object):
	def reverseList(self, head):
		"""
		:type head: ListNode
		:rtype: ListNode
		"""
		# 申请两个节点,pre和 cur,pre指向None
		pre = None
		cur = head
		# 遍历链表,while循环里面的内容其实可以写成一行
		while cur:
			# 记录当前节点的下一个节点
			tmp = cur.next
			# 然后将当前节点指向pre
			cur.next = pre
			# pre和cur节点都前进一位
			pre = cur
			cur = tmp
		return pre	

C++ implementation:

/**
 * 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* reverseList(ListNode* head) {
        ListNode* pre = nullptr;
        ListNode* temp = head;
        while(head){
            temp = head->next;
            head->next = pre;
            pre = head;
            head = temp;
        }
        return pre;
    }
};

Idea 2. Recursive method

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        # pre = None
        # cur = head

        # while cur:
        #     node = cur.next
        #     cur.next = pre
        #     pre = cur
        #     cur = node
        # return pre
        if head is None or head.next is None:
            return head
        new_node = self.reverseList(head.next)
        print('head.val',head.val)
        head.next.next = head
        head.next = None
        return new_node

2-2: Rotating linked list

Ideas:

After forming a circular list, the moving node is found to be split

python:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def rotateRight(self, head: ListNode, k: int) -> ListNode:
        if k == 0 or head is None or head.next is None:
            return head
        #计算链表长度
        cur = head        
        n = 1
        while cur.next:
            cur = cur.next
            n += 1
        # print('==n:', n)        
        add = n - k % n
        if add == n:#k是n的整数倍直接返回原节点
            return head
        cur.next = head #构成环
        while add:
            cur = cur.next
            add -= 1
        new_head = cur.next#找到移动后的开始节点
        cur.next = None#拆开
        return new_head

C++ implementation:

/**
 * 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* rotateRight(ListNode* head, int k) {
        if(k == 0 || head == nullptr || head->next == nullptr){
            return head;
        }
        int n = 1;//得到环长度
        ListNode* cur = head;
        while(cur->next){
            cur = cur->next;
            n++;
        }
        //找到移动的add长度
        int add = n - k % n;
        if(add == n){
            return head;
        }
        cur->next = head;//构成环
        while(add){
            cur = cur->next;
            add--;
        }
        ListNode* new_node = cur->next;
        cur->next = nullptr;//拆环
        return new_node;


    }
};

3-1. Merge two sorted linked lists

Idea: Introduce a pointer head python implementation

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:

        head = ListNode(0)
        node = head

        while l1 and l2:
            if l1.val < l2.val:
                node.next = l1
                l1 = l1.next
            else:
                node.next = l2
                l2 = l2.next
            node = node.next
        if l1 is not None:
            node.next= l1
        if l2 is not None:
            node.next= l2
        return head.next

C++ implementation:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* new_head = new ListNode(0);
        ListNode* node = new_head;

        while(l1!=NULL && l2 !=NULL){
            if(l1->val<l2->val){
                node->next = l1;
                l1 = l1->next;
            }
            else{
                node->next  = l2;
                l2 = l2->next;                
            }
            node = node->next;
        }

        if (l1!=NULL){
            node->next = l1;
        }
        if(l2!=NULL){
            node->next = l2;
        }
        return new_head->next;
    }
};

3-2. Merge K ascending linked lists

Idea 1: The previous question merges the two into a for loop to merge in order

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwo(self, l1, l2):
        if l1 is None:
            return l2
        if l2 is None:
            return l1
        head = ListNode(0)
        node = head
        while l1 and l2:
            if l1.val <l2.val:
                node.next = l1
                l1 = l1.next
            else:
                node.next = l2
                l2 = l2.next
            node = node.next
        if l1:
            node.next = l1
        if l2:
            node.next = l2
        return head.next

    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        ans  = None
        for i in range(len(lists)):
            ans = self.mergeTwo(ans,lists[i])
        return ans

c++:

/**
 * 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* mergtwo(ListNode* l1, ListNode* l2){
        if(l1==nullptr){
            return l2;
        }
        if(l2==nullptr){
            return l1;
        }
        ListNode* new_head= new ListNode(0);
        ListNode* node = new_head;
        while(l1 && l2){
            if(l1->val<l2->val){
                node->next = l1;
                l1= l1->next;
            }
            else{
                node->next = l2;
                l2= l2->next;
            }
            node = node->next;
        }
        if(l1){
            node->next = l1;
        }
        if(l2){
            node->next = l2;
        }
        return new_head->next;
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode* res = nullptr;
        for (int i=0;i<lists.size();i++){
            res = mergtwo(res,lists[i]);
        }
        return res;
    }
};

Idea 2: Divide and conquer merge 1

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwo(self, l1, l2):
        if l1 is None:
            return l2
        if l2 is None:
            return l1
        head = ListNode(0)
        node = head
        while l1 and l2:
            if l1.val <l2.val:
                node.next = l1
                l1 = l1.next
            else:
                node.next = l2
                l2 = l2.next
            node = node.next
        if l1:
            node.next = l1
        if l2:
            node.next = l2
        return head.next
    def mergeSort(self, lists, left, right):
        if left==right:
            return lists[left]
        middle = left + (right-left)//2
        # print('== middle:', middle)
        l1 = self.mergeSort(lists,left,middle)
        # print('== l1:', l1)
        l2 = self.mergeSort(lists,middle+1,right)
        return self.mergeTwo(l1, l2)


    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        # print('==hahah')
        if len(lists)==0:
            return None
        return self.mergeSort(lists,0,len(lists) - 1)

C++ implementation: 

/**
 * 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* mergetwo(ListNode* l1, ListNode* l2){
        if(l1==nullptr){
            return l2;
        }
        if(l2==nullptr){
            return l1;
        }
        ListNode* new_head= new ListNode(0);
        ListNode* node = new_head;
        while(l1 && l2){
            if(l1->val<l2->val){
                node->next = l1;
                l1= l1->next;
            }
            else{
                node->next = l2;
                l2= l2->next;
            }
            node = node->next;
        }
        if(l1){
            node->next = l1;
        }
        if(l2){
            node->next = l2;
        }
        return new_head->next;
    }
    ListNode* mergesort(vector<ListNode*>& lists,int left, int right){
        if(left==right){
            return lists[left];
            }
        int middle = left+(right -left)/2;
        ListNode* l1 = mergesort(lists,left,middle);
        ListNode* l2 = mergesort(lists,middle+1,right);
        return mergetwo(l1,l2);
        
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        // ListNode* res = nullptr;
        // for (int i=0;i<lists.size();i++){
        //     res = mergtwo(res,lists[i]);
        // }
        // return res;
        if (lists.size()==0){
            return nullptr;
        }
        return mergesort(lists,0,lists.size()-1);
    }
};

Idea 3: Branch merging 2 Merging sorting with reference to sorting algorithm https://blog.csdn.net/fanzonghao/article/details/81270601


class Solution:
    def mergeTwo(self, l1, l2):
        if l1 is None:
            return l2
        if l2 is None:
            return l1
        head = ListNode(0)
        node = head
        while l1 and l2:
            if l1.val < l2.val:
                node.next = l1
                l1 = l1.next
            else:
                node.next = l2
                l2 = l2.next
            node = node.next
        if l1:
            node.next = l1
        if l2:
            node.next = l2
        return head.next
    def mergeSort(self, L):
        if len(L) <= 1:
            return L[0]
        mid = len(L) // 2 
        l1 = self.mergeSort(L[:mid])
        l2 = self.mergeSort(L[mid:])
        return self.mergeTwo(l1, l2)
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        if len(lists)==0:
            return None
        return self.mergeSort(lists)

3 -3. Combine two ordered linked lists

 

Idea: The recursive termination condition is that the node is None.

1. Recursion 

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        #递归的终止条件
        if l1 is None:
            return l2
        elif l2 is None:
            return l1    

        elif l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next,l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1,l2.next)
            return l2
        

2. Iterative method:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        fake_head_node  = ListNode(0)

        cur = fake_head_node

        while l1 and l2:
            if l1.val<l2.val:
                cur.next = l1
                l1 = l1.next
            else:
                cur.next = l2
                l2 = l2.next            
            cur = cur.next
        
        if l1:
            cur.next = l1
        else:
            cur.next = l2

        return fake_head_node.next
            

3-4. Sort linked list

Idea 1: Merge sorting first find the center point through the fast and slow pointers for truncation and then recursively disassemble and merge.

python code:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def merge(self, left, right):
        res = ListNode(0)
        temp = res
        while left and right:
            if left.val < right.val:
                temp.next, left = left, left.next
            else:
                temp.next, right = right, right.next
            temp = temp.next
        temp.next = left if left else right
        return res.next

    def sortList(self, head: ListNode) -> ListNode:
        if head is None or head.next is None:
            return head 
        #快慢指针找到链表中心点
        slow, fast = head, head.next
        while fast and fast.next:
            fast, slow = fast.next.next, slow.next
        mid, slow.next = slow.next, None#将找到的中心点进行截断故 slow.next = None
        
        left, right = self.sortList(head), self.sortList(mid)#递归一直进行拆分

        return self.merge(left, right)#合并操作
        

c++ 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* mergetwo(ListNode* l1,ListNode* l2){
        ListNode* new_head = new ListNode(0);
        ListNode* node = new_head;
        while(l1 && l2){
            if(l1->val<l2->val){
                node->next = l1;
                l1 = l1->next;
            }
            else{
                node->next = l2;
                l2 = l2->next;
            }
            node = node->next;
        }
        if(l1){
            node->next = l1;
        }
        if(l2){
            node->next = l2;
        }
        return new_head->next;
    }
    ListNode* sortList(ListNode* head) {
        if(head==nullptr || head->next==nullptr){
            return head;
        }
        ListNode* slow = head;
        ListNode* fast = head->next;
        while(fast && fast->next){
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode* middle = slow->next;
        slow->next = nullptr;
        ListNode* l1 = sortList(head);
        ListNode* l2 = sortList(middle);
        return mergetwo(l1,l2);
    }
};

Idea 2: Merging is also recursive

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    # def merge(self, left, right):
    #     res = ListNode(0)
    #     temp = res
    #     while left and right:
    #         if left.val < right.val:
    #             temp.next, left = left, left.next
    #         else:
    #             temp.next, right = right, right.next
    #         temp = temp.next
    #     temp.next = left if left else right
    #     return res.next
    def merge(self,left,right):
        if left is None:
            return right
        if right is None:
            return left
        if left.val < right.val:
            left.next = self.merge(left.next, right)
            return left
        else:
            right.next = self.merge(left, right.next)
            return right

    def sortList(self, head: ListNode) -> ListNode:
        if head is None or head.next is None:
            return head 
        #快慢指针找到链表中心点
        slow, fast = head, head.next
        while fast and fast.next:
            fast, slow = fast.next.next, slow.next
        mid, slow.next = slow.next, None#将找到的中心点进行截断故 slow.next = None
        
        left, right = self.sortList(head), self.sortList(mid)#递归一直进行拆分

        return self.merge(left, right)#合并操作
        

3-5. Add two numbers 

Idea: Open a head and use a pointer to traverse. What you need to pay attention to is carry

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        head = ListNode(0)
        new_node = head
        carry = 0
        while l1 and l2:
            new_node.next =ListNode(l1.val+l2.val+carry)
            carry = new_node.next.val//10 
            new_node.next.val = new_node.next.val%10
            l1 = l1.next
            l2= l2.next
            new_node = new_node.next
        # print(carry)
        while l1:
            new_node.next = ListNode(l1.val+carry)
            carry  = new_node.next.val//10
            new_node.next.val = new_node.next.val%10
            l1 = l1.next
            new_node = new_node.next
        while l2:
            new_node.next =  ListNode(l2.val+carry)
            carry  = new_node.next.val//10
            new_node.next.val = new_node.next.val%10
            l2 = l2.next
            new_node = new_node.next
        if carry:
            new_node.next =  ListNode(carry)
        return head.next

C++ implementation:

/**
 * 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* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* head = new ListNode(0);
        ListNode* new_head = head;
        int carry = 0;
        while(l1 && l2){
            new_head->next = new ListNode(l1->val + l2->val + carry);
            carry = new_head->next->val/10;
            new_head->next->val = new_head->next->val%10;            
            new_head = new_head->next;
            l1 = l1->next;
            l2 = l2->next;
        }

        while(l1){
            new_head->next = new ListNode(l1->val + carry);
            carry = new_head->next->val/10;
            new_head->next->val = new_head->next->val%10;  
            new_head = new_head->next;
            l1 = l1->next;
        }
        while(l2){
            new_head->next = new ListNode(l2->val + carry);
            carry = new_head->next->val/10;
            new_head->next->val = new_head->next->val%10;  
            new_head = new_head->next;
            l2 = l2->next;
        }
        if(carry){
            new_head->next = new ListNode(carry);
        }
        return head->next;



    }
};

 

4-1 . Circular linked list

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        #快慢指针 人追人
        slow,fast = head,head

        while fast:
            if fast and fast.next:
                slow = slow.next
                fast=fast.next.next
            else:
                return False
            if slow==fast:
                return True
            
            
        return False

C++ implementation:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast){
            if(fast && fast->next){
                slow = slow->next;
                fast = fast->next->next;
            }
            else{
                return false;
            }
            if(slow==fast){
                return true;
            }
        }
        return false;
    }
};

4-2. Given a linked list with loops, implement an algorithm to return to the beginning node of the loop.

 

Suppose there are two pointers, namely fast and slow pointers. The fast pointer takes two steps at a time, and the slow pointer advances one step at a time. If there is a ring, the two pointers must meet;

Proof: Assuming that the fast pointer really crosses the slow pointer, and the fast pointer is at position i+1, and the slow pointer is at position i, then in the previous step, the fast pointer is at position i-1 and the slow pointer is also at position i-1, They met.

A: starting point of the linked list
B: starting point of the ring
C: meeting point
X: the distance from the
starting point of the ring to the meeting point Y: the distance from the starting point of the linked list to the starting point of the ring
R: the length of the ring
S: the distance traveled during the first encounter

1. The distance traveled by the slow pointer slow the first encounter S1 = Y + X; (11)
The distance traveled by the fast pointer fast first encounter S2=2S1 = Y + X + NR; (2)
Description: Fast pointer The speed of is twice the speed of the slow pointer, and the distance in the same time should be twice that of the slow pointer. Y + X + NR is because the fast pointer may pass N turns before the two meet;
substitute (1) into (2) Get: Y = NR -X; 

2. When returning the slow pointer to point A, the full pointer and the fast pointer move at the same time, and they meet at point B. This is the ring node.

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        slow = head
        fast = head;
        while fast:
            if fast and fast.next:
                slow = slow.next
                fast = fast.next.next
            else:
                return None
            if slow==fast:
                break
        if fast ==None or fast.next==None:
            return None
        slow= head
        while slow!=fast:
            slow = slow.next
            fast = fast.next

        return slow

C++ implementation:

/**
 * 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) {
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast){
            if(fast && fast->next){
                slow = slow->next;
                fast = fast->next->next;
            }
            else{
                return NULL;
            }
            if(slow==fast){
                break;
            }
        }
        if(!fast || !fast->next){
            return NULL;
        }
        slow = head;
        while(slow!=fast){
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
        
    }
};

4-3 . Linked lists intersect

For example, this question should be a more obvious double-pointer question. If an algorithm can be implemented to make the two pointers go from point A and point B to point C respectively, after the two pointers go to C respectively, they each start from the starting point of the other pointer. , That is, the second time the A pointer walks from point B, the same is true for the B pointer. In this way, the path length of the A pointer AO + OC + BO must be equal to the path length of the B pointer BO + OC + AO, which means It means that the two pointers will definitely meet at O ​​point in the second round of walking. After they meet, the condition to exit the loop is reached. The code is as follows:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        index_a =  headA
        index_b = headB
        while index_a !=index_b:
            if index_a !=None:
                index_a = index_a.next
            else:
                index_a = headB
            if index_b != None:
                index_b = index_b.next
            else:
                index_b = headA
        return index_a

            

C++ implementation:

/**
 * 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) {
        ListNode* node_A = headA;
        ListNode* node_B = headB;
        while(node_A!=node_B){
            if(node_A!=NULL){
                node_A=node_A->next;
            }
            else{
                node_A = headB;
            }
            if(node_B!=NULL){
                node_B=node_B->next;
            }
            else{
                node_B = headA;
            }
        }
        return node_A;
        
        
    }
};

4-4. The first common node of two linked lists

Idea: Double pointers and two pointers take turns to go through their respective distances, so that the encounter is a public node. For the case where there is no public node, it is necessary to judge that the own node is not none, not .next is none, and exchange pointers, otherwise you will fall into Infinite loop, and the output is none at this time.

python

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        first_head = headA
        second_head = headB
        while first_head !=second_head:
            if first_head is not None:
                first_head = first_head.next 
            else:
                first_head = headB
            if second_head is not None:
                second_head = second_head.next
            else:
                second_head = headA
        # print(first_head)
        return first_head

c++:

/**
 * 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) {
    ListNode *first_node;
    first_node = headA;
    ListNode *second_node;
    second_node= headB;
    while(first_node != second_node)
    {
        if(first_node !=NULL)
        {
            first_node = first_node->next;
        }
        else
        {
            first_node = headB;
        }

        if(second_node !=NULL)
        {
            second_node = second_node->next;
        }
        else
        {
            second_node = headA;
        }
    }
    return first_node;
        
    }
};

5-1 . Enter the head node of a linked list, and return the value of each node from the end to the beginning (return with an array).

1. Borrow the stack

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        stack = []
        while head:
            stack.append(head.val)
            head = head.next
        return stack[::-1]

c++:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int> res;
        while(head){
            res.push_back(head->val);
            head = head->next;
        }
        reverse(res.begin(),res.end());
        return res;

    }
};

2. Recursive backtracking

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        if head:
            return self.reversePrint(head.next)+[head.val]
        else:
            return []

5-2 . Please judge whether a linked list is a palindrome linked list

Use the list to copy the list value, and judge whether it is a palindrome string

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        stack= []
        while head:
            stack.append(head.val)
            head = head.next
        return stack==stack[::-1]

C++ implementation:

/**
 * 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:
    bool isPalindrome(ListNode* head) {
        vector<int> res;
        while(head){
            res.push_back(head->val);
            head = head->next;
        }
        int left=0;
        int right=res.size()-1;
        while(left<right){
            if(res[left]==res[right]){
                left+=1;
                right-=1;
            }
            else{
                return false;
            }
        }
        return true;

    }
};

5-3. Separate Linked List

Idea: Open two large and small nodes to point to those greater than x and less than x. After the traversal is completed, they can be merged

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        small_head = ListNode(0)
        large_head = ListNode(0)

        small_node = small_head
        large_node = large_head


        while head:
            if head.val < x:
                small_node.next = head
                small_node = small_node.next
            else:
                large_node.next  = head
                large_node = large_node.next
            head= head.next
        large_node.next = None
        small_node.next = large_head.next
        return small_head.next

c++ writing:

/**
 * 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* partition(ListNode* head, int x) {
        ListNode* small_head = new ListNode(0);
        ListNode* big_head = new ListNode(0);
        ListNode* small_node =small_head;
        ListNode* big_node = big_head;
        while(head){
            if (head->val<x){
                small_node->next = head;                
                small_node = small_node->next;
            }
            else{
                big_node->next = head;
                big_node = big_node->next;
            }
            head = head->next;
        }
        big_node->next = nullptr;
        small_node->next = big_head->next;
        return small_head->next;
    }
};

6-1. The binary tree is expanded into a linked list

Idea: It can be seen that the nodes traversed according to the preorder are all placed on the right subtree

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def help(self, node):
        if node is not None:
            self.res.append(node)
            self.help(node.left)
            self.help(node.right)
    def flatten(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        self.res = []
        self.help(root)
        # print(self.res)
        length = len(self.res)
        for i in range(1,length):
            pre,cur = self.res[i-1],self.res[i]
            pre.left = None
            pre.right = cur
        return root

C++ implementation:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<TreeNode* >res;

    void help(TreeNode* node){
        if(node){
            res.push_back(node);
            help(node->left);
            help(node->right);
        }
    }
    void flatten(TreeNode* root) {
        help(root);
        for(int i=1;i<res.size();i++){
            TreeNode* pre = res[i-1];
            TreeNode* cur =  res[i];
            pre->left = nullptr;
            pre->right = cur;
        }
        // return root;
    }
};

 

Guess you like

Origin blog.csdn.net/fanzonghao/article/details/113889824