Statement: topic source: 1. LeetCode 2. newcoder.
Title List:
- Delete all nodes in the linked list equal to the given value val.
- Reverses a single chain table.
- Given a non empty single linked list with head node, the middle node of the linked list is returned. If there are two intermediate nodes, the second intermediate node is returned.
- Input a list and output the k last node in the list.
- Merge two ordered lists into a new ordered list and return. The new linked list is composed of all nodes of two given linked lists.
- Given a sort list, delete all duplicate elements so that each element appears only once.
1. Delete all nodes in the linked list equal to the given value val.
Title Link: Remove linked list elements
Example:
Input: 1 - > 2 - > 6 - > 3 - > 4 - > 5 - > 6, Val = 6
Output: 1 - > 2 - > 3 - > 4 - > 5
This topic is relatively simple, mainly to investigate the understanding of the chain list structure.
Solution: define two node type pointers, one node pointer is used to determine whether the value of the current node is equal to val, and the other node pointer is always in the front of the current node. If the value of the current node is equal to val, the current node will be deleted until the entire linked list is traversed. The following codes are for reference only:
struct ListNode* removeElements(struct ListNode* head, int val){ if(head == NULL){ return head; } struct ListNode *pre = head; struct ListNode *cur = head->next; while(cur != NULL){ if(cur->val == val){ pre->next = cur->next; free(cur); } else{ pre = cur; } cur = pre->next; } if(head->val == val){ return head->next; } return head; }
2. Reverse a single chain table.
Title Link: Inverted list
Example:
Input: 1 - > 2 - > 3 - > 4 - > 5 - > null
Output: 5 - > 4 - > 3 - > 2 - > 1 - > null
This paper introduces three solutions:
Solution 1: point the first node to NULL, the next value of each other node to the previous node, and return the last node traversed.
This solution is simple, easy to understand and recommended.
Solution 2: it is applicable to the linked list of leading nodes. If there is no leading node, a leading node can also be created. The method is to start from the second node, use the head insertion method for each traversed node, and finally return the head node to get a flipped list.
The results of one operation are as follows:
This method is actually the same as solution 1, but the logic is different:
Solution 1 needs to create another pointer variable to save the next node to be traversed, and the pointer to the current node, the previous node and the next node must be constantly moving;
In solution 2, only two pointer variables are needed, one is always pointing to the head node, and the other is always pointing to the head node. The two pointers do not move and only need to use the head insertion operation continuously.
Solution 3: recursion, starting from the first node of the list, using recursion until accessing the last node, and then making the node point to the node recursive to the previous layer, similar to the idea of solution 1, but reversed:
The following is the reference code for solution 3:
struct ListNode* reverse(struct ListNode* head){ if(head->next == NULL){ return head; } struct ListNode *List = reverse(head->next); List->next = head; head->next = NULL; return head; }
struct ListNode* reverseList(struct ListNode* head){ if(head == NULL){ return head; } struct ListNode *later = head; while(later->next != NULL){ later=later->next; } reverse(head); return later; }
Reference code for solution 2:
struct ListNode* reverseList(struct ListNode* head){ if(head == NULL){ return head; } struct ListNode *plist = (struct ListNode *)malloc(sizeof(struct ListNode)); plist->next = NULL; struct ListNode *cur = head; struct ListNode *next = cur; while(next != NULL){ next = next->next; cur->next = plist->next; plist->next = cur; cur = next; } head = plist->next; free(plist); return head; }
3. Given a non empty single linked list with head node, return the middle node of the linked list. If there are two intermediate nodes, the second intermediate node is returned.
Title Link: Middle node of linked list
Example 1:
Input: [1,2,3,4,5]
Output: node 3 in this list (serialization form: [3,4,5])
The returned node value is 3. (the serialization expression of the evaluation system for this node is [3,4,5])
Note that we return an object ans of type ListNode, as follows:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL.
Example 2:
Input: [1,2,3,4,5,6]
Output: node 4 in this list (serialization form: [4,5,6])
Since the list has two intermediate nodes with values of 3 and 4, we return the second node.
The idea of this problem is very simple. Set the speed two pointers to start from the beginning node at the same time. The slow pointer moves one node backward each time, and the fast pointer moves two nodes until the fast pointer traverses to the last node and returns the slow pointer.
Reference code:
struct ListNode* middleNode(struct ListNode* head){ if(head == NULL){ return NULL; } struct ListNode *MidNode = head; struct ListNode *cur = head; while(cur && cur->next != NULL){ cur = cur->next->next; MidNode = MidNode->next; } return MidNode; }
4. Input a list and output the k-th last node in the list.
Title Link: Output the last k nodes in the single chain table
Enter a description:
Input specification
1. Number of input link list nodes
2 input the value of the linked list
3 enter the value of k
Output Description:
Output an integer
Solution 1: the idea of solution 1 is the same as that of the previous problem. Set two pointers: fast pointer and slow pointer. The fast pointer first moves k nodes backward, and then the slow pointer and the fast pointer move at the same speed until the fast pointer points to null and returns to the slow pointer.
Solution 2: another speculative method is to use the head insertion method to create a linked list, and then return the k-th node of the linked list.
The following is the algorithm code of solution 1:
#include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct ListNode { int val; struct ListNode* next; }ListNode; ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { if(k == 0){ return pListHead; } ListNode *end = pListHead->next; for (unsigned int i = 1; i < k; ++i) { end = end->next; } ListNode *dest = pListHead->next; while (end->next != NULL) { dest = dest->next; end = end->next; } return dest; } void CreatList(ListNode* pListHead, int length) { ListNode* pre = pListHead; for (int i = 0; i < length; ++i) { ListNode* cur = (ListNode *)malloc(sizeof(ListNode)); scanf("%d ", &cur->val); pre->next = cur; pre = pre->next; } pre->next = NULL; } int main() { int length; while(scanf("%d", &length) != EOF){ ListNode* pListHead; pListHead = (ListNode *)malloc(sizeof(ListNode)); pListHead->val = 0; CreatList(pListHead, length); int k; scanf("%d", &k); printf("%d\n", FindKthToTail(pListHead, k)->val); } return 0; }
5. Merge two ordered lists into a new ordered list and return. The new linked list is composed of all nodes of two given linked lists.
Title Link: Merge two ordered lists
Example:
Input: 1 - > 2 - > 4, 1 - > 3 - > 4
Output: 1 - > 1 - > 2 - > 3 - > 4 - > 4
It is known that the two linked lists are ordered, so only two pointers need to be set to point to two linked lists respectively, and the two pointers need to be moved continuously to compare the value of the current position. The node with smaller value will be inserted into the new linked list first until a linked list is accessed. Finally, judge whether there is a linked list that has not been visited completely, and insert the subsequent part of the linked list to the end of the new linked list.
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){ struct ListNode *newl; if(l1 == NULL){ return l2; }else if(l2 == NULL){ return l1; } if(l1->val > l2->val){ newl = l2; l2 = l2->next; } else{ newl = l1; l1 = l1->next; } struct ListNode *cur = newl; while(l1 != NULL && l2 != NULL){ if(l1->val > l2->val){ cur->next = l2; l2 = l2->next; cur = cur->next; } else{ cur->next = l1; l1 = l1->next; cur = cur->next; } } if(l1 == NULL){ cur->next = l2; } else{ cur->next = l1; } return newl; }
6. Given a sort list, delete all duplicate elements so that each element appears only once.
Title Link: Delete duplicate elements in linked list
Example 1:
Input: 1 - > 1 - > 2
Output: 1->2
Example 2:
Input: 1 - > 1 - > 2 - > 3 - > 3
Output: 1 - > 2 - > 3
There is still no difficulty in this problem: create two pointers, one cur points to the current node, and one tmp points to the next node. If the two nodes are equal, delete the nodes pointed by tmp until the next node pointed by cur is not equal to the value of the node, and then move cur backward... Until tmp is empty, exit.
The reference code is as follows:
struct ListNode* deleteDuplicates(struct ListNode* head){ struct ListNode* cur = head; struct ListNode* tmp; while(cur && cur->next != NULL){ tmp = cur->next; if(tmp->val == cur->val){ cur->next = tmp->next; free(tmp); continue; } cur = cur->next; } return head; }