算法通关村第二关——链表反转拓展|白银挑战

1指定区间反转

92. 反转链表 II

1.1头插法

  1. 带虚拟节点dummyNode插入操作,方便处理边界情况
  2. pre指针,定位到反转的起始位置的前一个节点left-1
  3. cur指针,指向需要反转的起始节点
  4. for循环进行反转
    1. 保存cur的下一个节点next
    2. 将cur.next指向next的下一个节点(断开连接)
    3. 将next的next指向pre的下一个节点(接上反转后的新链表)
    4. 将pre的下一个节点指向next(接上反转后的节点)
    5. 更新pre和cur指针
  5. 循环结束后,中间部分链表完成反转
  6. 返回dummyNode.next
public ListNode reverseBetween(ListNode head,int left,int right){
    ListNode dummyNode=new ListNode(-1);
    dummyNode.next=head;
    ListNode pre=dummyNode;
    for(int i=0;i<left-1;i++){
        pre=pre.next;
    }
    ListNode cur=pre.next;
    ListNode next;
    for(int i=0;i<right-left;i++){
        next=cur.next;
        cur.next=next.next;
        next.next=pre.next;
        pre.next=next;
    }
    return dummyNode.next;
}

1.2穿针引线法

  1. 使用虚拟节点dummyNode
  2. pre指针,定位到饭庄的其实位置的前一个节点left-1
  3. 从pre再走right-left+1步,来到right节点
  4. 截取子链表,切断链接
  5. 反转子链表
  6. 接回原来链表,把前驱pre的next指针指向反转以后的链表头节点,把反转以后的链表的尾节点的next指针指向后继succ
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(int i=0;i<left-1;i++){
        pre=pre.next;
    }
// 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
    ListNode rightNode=pre
    for(int i=0;i<right-left+1;i++){
        rightNode=rightNode.next;
    }
// 第 3 步:切断出一个子链表(截取链表)
    ListNode leftNode=pre.next;
    ListNode succ=rightNode.next;
// 注意:切断链接
    pre.next=null;
    rightNode.next=null;
// 第 4 步:同第 206 题,反转链表的子区间
    reverseList(leftNode);
// 第 5 步:接回到原来的链表中
    pre.next=rightNode;
    leftNode.next=succ;
    return dummyNode.next;
}
public ListNode reverseList(ListNode head){
    ListNode prev=null;
    ListNode curr=head;
    while(curr!=null){
        ListNode next=curr.next;
        curr.next=prev;
        prev=curr;
        curr=next;
    }
    return prev;
}

2两两交换链表中的节点

24. 两两交换链表中的节点

  1. 创建虚拟节点,连接原链表
  2. 定义当前节点cur,初始化dummy节点
  3. 循环遍历,每次考虑3个节点:cur、cur.next(节点1)、cur.next.next(节点2)
  4. 实现交换:
    1. cur.next=节点2
    2. 节点1.next=节点2.next
    3. 节点2.next=节点1
  5. 当前节点cur更新为节点1
  6. 返回dummy.next
public ListNode swapPairs(ListNode head){
    ListNode dummyHead=new ListNode(0);
    dummyHead.next=head;
    ListNode cur=dummyHead;
    while(cur.next!=null&&cur.next.next!=null){
        ListNode node1=cur.next;
        ListNode node2=cur.next.next;
        cur.next=node2;
        node1.next=node2.next;
        node2.next=node1;
        cur=node1;
    }
    return dummyHead.next;
}

你可能感兴趣的:(算法,链表,数据结构)