翻转链表 ——迭代法
反转整个链表
反转整个链表
迭代法:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre=nullptr;
while(head!=nullptr){
ListNode* next=head->next;
head->next=pre;
pre=head;
head=next;
}
return pre;
}
};
递归法:
java:
class Solution {
public ListNode reverseList(ListNode head) {
if(head.next==null){
return head;
}
ListNode last=reverseList(head.next);
head.next.next=head;
head.next=null;
return last;
}
}
c++:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==nullptr){
return nullptr;
}
if(head->next==nullptr){
return head;
}
ListNode* last=reverseList(head->next);
head->next->next=head;
head->next=nullptr;
return last;
}
};
反转链表前 N 个节点
无非是加个n作为限制而已
class Solution {
ListNode reverseN(ListNode head, int n) {
ListNode pre=null,p=head;
while (p.next!=null && n>0){
n--;
ListNode next=p.next;
p.next=pre;
pre=p;
p=next;
}
head.next=p;
return pre;
}
}
反转任意区间的链表
反转链表任意区间的链表
越是直白越不出错!
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
// 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
// 建议写在 for 循环里,语义清晰
for (int i = 0; i < left - 1; i++) {
pre = pre.next;
}
// 第 2 步:从虚拟头节点走 right 步,来到 right 节点
ListNode rightNode = dummyNode;
for (int i = 0; i < right; i++) {
rightNode = rightNode.next;
}
// 第 3 步:切断出一个子链表(截取链表)
ListNode leftNode = pre.next;
ListNode rightNext = rightNode.next;
// 切断链表防止成环
pre.next = null;
rightNode.next = null;
// 第 4 步:反转链表的子区间
reverseLinkedList(leftNode);
// 第 5 步:接回到原来的链表中
pre.next = rightNode;
leftNode.next = rightNext;
return dummyNode.next;
}
private void reverseLinkedList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
}
}
K 个一组翻转链表——递归法
c++:
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(head==nullptr){
return head;
}
ListNode* p=head;
for(int i=0;i<k-1;i++){
if(p->next==nullptr){
return head;
}
p=p->next;
}
ListNode* nextHead=reverseKGroup(p->next,k);
p->next=nullptr;
p=head;
ListNode* pre=nullptr;
while(p!=nullptr){
ListNode* next=p->next;
p->next=pre;
pre=p;
p=next;
}
head->next=nextHead;
return pre;
}
};
java:
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if (head==null || head.next==null){
return head;
}
ListNode p=head;
for (int i = 0; i < k; i++) {
if (p==null){ //还没走k步,节点就不够了
return head;
}
p=p.next;
}
ListNode newHead =reverse(head,p);
ListNode last = reverseKGroup(p, k);
head.next=last;
return newHead;
}
private ListNode reverse(ListNode head, ListNode tail) {
ListNode pre=null;
ListNode q=head;
while (q!=tail){
ListNode next=q.next;
q.next=pre;
pre=q;
q=next;
}
return pre;
}
}