链表
单链表
1.2021-4-14 指定区间单链表节点反转
题目:
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
示例
输入
head = [1,2,3,4,5], left = 2, right = 4
输出
[1,4,3,2,5]
思路:
两个考点
第一个:当没有头节点的时候,需要自己创建一个
ListNode *myhead=new ListNode(0);
myhead->next=head;
第二个反转链表结束后需要获取的两个节点,
以[1 2 3 4 5] 2 4为例,我们需要让1->4
还需要让2->5。
那么相当于指定pre和now,pre在4时,now在5时结束。
然后需要让1->next->next指向now,1->next指向pre。
因此我们首先要先让hh=myhead,移动到1的位置。
即移动left-1次。
此时让pre=hh->next,now=hh->next->next。
另外整个反转循环应该是2到4,即right-left次。
代码:
/**
* 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* reverseBetween(ListNode* head, int left, int right) {
ListNode* myhead=new ListNode(0);
myhead->next=head;
ListNode* hh=myhead;
right-=left;
while(left>1){
hh=hh->next;
left--;
}
ListNode* pre=hh->next;
ListNode* now=hh->next->next;
while(right>0){
ListNode* tmp=now->next;
now->next=pre;
pre=now;
now=tmp;
right--;
}
hh->next->next=now;
hh->next=pre;
return myhead->next;
}
};
2.2021-4-15 K 个一组翻转链表
题目:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例
提示
列表中节点的数量在范围 sz 内
1 <= sz <= 5000
0 <= Node.val <= 1000
1 <= k <= sz
思路:
这道题可以和反转链表和2个一组反转链表放在一起看。
其实是k个一组进行一次翻转。
首先在不满足k个剩余时退出,我们要用tmp1=当前开头->next,遍历到末尾,看是否cnt==k。
这里要非常注意tmp1是从当前开头的下一个开始,这样如果剩余刚好为k-1时,tmp1在前进k-1次时,tmp->next会为nullptr。
下个注意点就是在k个反转后要记录tmp3=h->next,处理完以后h=tmp3。
代码:
/**
* 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* reverseKGroup(ListNode* head, int k) {
if(k<=1)return head;
ListNode* h =new ListNode(0);
ListNode* mh =h;
h->next=head;
while(true){
ListNode* tmp1 =mh->next;
int cnt=0;
while(tmp1&&cnt!=k){
cnt++;
tmp1=tmp1->next;
}
if(cnt!=k)break;
ListNode* prev =mh->next;
ListNode* cur =prev->next;
while(cnt-->1){
ListNode* tmp2 =cur->next;
cur->next=prev;
prev=cur;
cur=tmp2;
}
ListNode* tmp3 =mh->next;
mh->next->next=cur;
mh->next=prev;
mh=tmp3;
}
return h->next;
}
};