Delete the last nth node of a linked list
Feel their knowledge of the linked list is not deep enough to understand, so there is no thought of double-pointer operation. My idea is this, first calculate the length of the entire list, and then traverse to the length minus n nodes, perform the delete operation.
Your own code:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* cur=head; ListNode *cou=head; int i=0; int count=1; while(cou->next!=NULL) { cou=cou->next; count++; } if(count==1) return NULL; if(count==n) {head=head->next; return head;} while(head->next!=NULL && i<count-1-n) { head=head->next; i++; } if(head->next!=NULL) { ListNode *temp; temp=head->next; head->next=temp->next; } return cur; }};
Believe that after reading the code, the logic of this code is quite strange, especially
if(count==1) return NULL; if(count==n) {head=head->next;return head;}
This code, the feeling is based on the test case to try out. It is true that my code will always remove the median element when it gets rid of the second-to-last element or [three-way] minus the third-to-last element, and the reason for the troubleshooting should be some problem with the head node's understanding. I think the head is the first pointer, Head->next is the initial node, but the meaning of this code seems to be the head is already the first nodes, so in the back of the time to judge some bugs. Of course, we are accustomed to using a more conventional approach is to use a two-pointer approach to solve the problem:
The Code of the Great God is released here:
class Solution{public:ListNode* removeNthFromEnd(ListNode* head,int n){if(!head->next) return NULL;LisNode *pre=head,*cur=head;for(int i=0;i<n;i++) cur=cur->next;if(!cur) return head->next;while(cur->next){cur=cur->next;pre=pre->next;}pre->next=pre->next->next;return head;}};
Let me explain the meaning of this code, define two pointers, two pointers are different n distances, so that when one of the pointers points to the end, the other pointer will naturally point to the position of the previous element we need to delete, and then perform the delete operation, which is very fast.
Reverse linked List
Feel this problem is some handsome, try to walk the logic, not like I thought before a new linked list and then the reverse traversal read the data, but this logic is a reverse one, with the dummy always point to the head node, cur always point to the current nodes, TMP Point to the next junction, The logic is to cur the next node that points to TMP, point TMP to the Head node, and then dummy to TMP and iterate again. It's really wise to think about this reversal. The code is as follows:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode* reverseList(ListNode* head) { if(!head) return head; ListNode *dummy=new ListNode(-1); dummy->next=head; ListNode *cur=head; while(cur->next) { ListNode *tmp=cur->next; cur->next=temp->next; tmp->next=dummy->next; dummy->next=tmp; } return dummy->next; }};
Merge two ordered linked lists
This question is relatively simple, is constantly judged; If a linked list is already late, it is OK to add all the following elements to the new linked list directly. The code is as follows:
/** * 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) { if(l1!=NULL&&l2==NULL) return l1; if(l1==NULL&&l2!=NULL) return l2; ListNode head(0); ListNode* l3=&head; while(l1!=NULL&&l2!=NULL) { if(l1->val<l2->val) { l3->next=l1; l1=l1->next; } else { l3->next=l2; l2=l2->next; } l3=l3->next; } if(l1!=NULL) l3->next=l1; if(l2!=NULL) l3->next=l2; return head.next; }};
Palindrome Chain List
The
is explained in the code comment, and it feels like a quick way to get to the center of the list (slow and fast applications, Fast->next->next is twice times the slow->next speed, when fast->next points to the end, Slow point to the middle!! )
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: bool isPalindrome(ListNode* head) { //O(n)时间表示不能有嵌套循环, O(1)空间表示不能再次添加新链表 if(!head||!head->next) return true; ListNode *slow=head,*fast=head; stack<int> s; s.push(head->val); while(fast->next!=NULL && fast->next->next!=NULL) { slow=slow->next; fast=fast=fast->next->next; //fast的速度是slow的两倍,这样就能保证slow最后能找到链表的中间 s.push(slow->val); } if(fast->next==NULL) s.pop(); //说明是奇数个,中间的就不用进行比较了,所以直接pop掉比较后面的 while(slow->next!=NULL) { slow=slow->next; int tmp=s.top(); s.pop(); if(tmp!=slow->val) return false; } return true; }};
Ring Linked List
The ring list is the simplest form of a circular list, that is, the end-to-end linkage. So if we specify two pointers, fast and slow. Two pointers at the same time start from the beginning, fast hands go two steps, slow the hands of a step, if the list has a ring, the two pointers will certainly meet at some point, if the linked list is not ring, fast will first reach null. Because of the continuous cycle, as long as there is a ring will meet, if there is no ring will definitely exist null.
The code is as follows:
/** * 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,*fast=head; while(fast!=NULL && fast->next!=NULL) { slow=slow->next; fast=fast->next->next; if(slow==fast) return true; } return false; }};
Leetcode Primary algorithm (chain list)