auto dummy = new ListNode(-1);
dummy->next = head;
以10道题目为例
做题步骤
代码示例
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {auto dummy = new ListNode(-1);dummy->next = head;auto fast = dummy;auto last = dummy;while(n--){fast = fast->next;} while(fast->next != nullptr){fast = fast->next;last = last->next;}auto tmap = last->next;last->next = last->next->next;delete tmap;return dummy->next;}
};
给一个节点将其删除(不是最后一个)
按照以前的删除做法不行(访问不到该节点的上一个节点)
将下一个节点覆盖到这个节点上,删除下一个节点
class Solution {
public:void deleteNode(ListNode* node) {node->val = node->next->val;node->next = node->next->next;}
};
class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {auto cur = head;while(cur){// 先进行判断指针的存在性if(cur->next && cur->val == cur->next->val){// auto tamp = cur->next;cur->next = cur->next->next;// delete tamp;}else{cur = cur->next;}}return head;}
};
class Solution {
public:ListNode* rotateRight(ListNode* head, int k) {if(head==nullptr) return head;int nums = 0;for(auto cur=head; cur; cur=cur->next){nums++;}k %= nums;auto fast = head;auto last = head;while(k--){fast = fast->next;}// 这里是访问到最后一个节点 假如是fast的话会访问到空指针while(fast->next){fast = fast->next;last = last->next;}fast->next = head;head = last->next;last->next = nullptr;return head;}
};
class Solution {
public:ListNode* swapPairs(ListNode* head) {if(head==nullptr || head->next==nullptr) return head;auto dummy = new ListNode(-1);dummy->next = head;for(auto p = dummy; p->next && p->next->next;){auto left = p->next;auto right = left->next;p->next = right;left->next = right->next;right->next = left;p = left;}return dummy->next;}
};
反转链表进行原地反转,只需进行考虑链表的节点反转次序
23. 需要记录当前节点的后一个
24. 需要进行反转,当前节点指向前一个
25. 移动到下一个
class Solution {
public:ListNode* reverseList(ListNode* head) {if(head==nullptr || head->next==nullptr) return head;auto pre = head;auto cur = pre->next;while(cur->next){auto after = cur->next;cur->next = pre;pre = cur;cur = after;}// cur的时候最后一个点没链接上cur->next = pre;head->next = nullptr;return cur;}
};
这个题目就是反转部分链表(给定区间上)
具体分为以下几个步骤
26. 反转区间上的链表
27. 将反转好的区间上的重新接到链表上
给出一个反转链表的模板
以下图为例
pre指向2
cur指向3
while(sum--){auto after = cur->next;cur->next = pre;pre = cur;cur = after;}
这段代码执行完之后 cur指向5, pre指向4
class Solution {
public:ListNode* reverseBetween(ListNode* head, int left, int right) {if(head==nullptr || head->next==nullptr || left==right) return head;auto dummy = new ListNode(-501);dummy->next = head;int sum = right - left;auto a = dummy;for(int i=0; inext;auto pre = a->next;auto cur = pre->next;while(sum--){auto after = cur->next;cur->next = pre;pre = cur;cur = after;}a->next->next = cur;a->next = pre;return dummy->next;}
};
题目描述
这个题要找两个链表的交点
暴力遍历复杂度是O(m*n)的时间复杂度
思考一下有这样的特点,两个链表的长度加上交点前的长度相等
代码示例
这道题目纯考数学能力
设置快慢指针,快指针走两步,慢指针走一步
设环的周长为c
慢指针走到c,那么快指针已经进圈,并且在圈里走了x,假设快指针距离交界点c为y
那么x+y=n∗cx+y=n*cx+y=n∗c
那么慢指针走y快指针必追上满指针
此时距离c点也是y
那么从开头到B点的距离就是yyy
那么再走x会回到点,因为x+y=n∗cx+y = n*cx+y=n∗c
class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {auto a = headA;auto b = headB;while(a != b){a = (a != NULL) ? a->next : headB;b = (b != NULL) ? b->next : headA;}return a;}
};
class Solution {
public:ListNode *detectCycle(ListNode *head) {auto fast = head;auto slow = head;while(fast){fast = fast->next;slow = slow->next;if(fast){fast = fast->next;}else{break;}if(fast == slow){slow = head;while(fast != slow){fast = fast->next;slow = slow->next;}return fast;}}return NULL; }
};
说白了就是将链表进行排序
但是这道题目有一个要求
常数级空间复杂度则递归不行
只能用for循环的归并排序
步骤如下
class Solution {
public:ListNode* sortList(ListNode* head) {auto dummy = new ListNode(-1);dummy->next = head;int n = 0;for(auto p=head; p; p=p->next) ++n;for(int i=1; iauto cur = dummy;for(int j=0; j+iauto left = cur->next;auto right = cur->next;for(int m=0; mnext;int l = 0;int r = 0;while(lif(left->val <= right->val){cur->next = left;cur = left;left = left->next;++l;}else{cur->next = right;cur = right;right = right->next;++r;}}while(lcur->next = left;cur = left;left = left->next;++l;}while(rcur->next = right;cur = right;right = right->next;++r;}cur->next = right;}}return dummy->next;}
};
上一篇:进程和线程的区别和联系
下一篇:C#等高级语言运行过程