资讯专栏INFORMATION COLUMN

[Leetcode] Swap Nodes in Pairs Reverse Nodes in k-

TZLLOG / 3020人阅读

摘要:三指针法复杂度时间空间思路基本的操作链表,见注释。注意使用头节点方便操作头节点。翻转后,开头节点就成了最后一个节点。

Swap Nodes in Pairs

Given a linked list, swap every two adjacent nodes and return its head.

For example, Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

三指针法 复杂度

时间 O(N) 空间 O(1)

思路

基本的操作链表,见line注释。注意使用dummy头节点方便操作头节点。

代码
public class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        // curr是待交换的两个节点前面那个节点
        ListNode curr = dummy;
        while(curr != null && curr.next != null && curr.next.next != null){
            ListNode third = curr.next.next.next;
            ListNode second = curr.next.next;
            ListNode first = curr.next;
            // 把第二个节点的next置为第一个节点
            second.next = first;
            // 把当前节点的next置为第二个节点
            curr.next = second;
            // 把第一个节点的next置为第三个节点
            first.next = third;
            // 将当前节点置为第一个节点,继续下一轮交换(此时first实际已经是第二个节点了)
            curr = first;
        }
        return dummy.next;
    }
}

不想用那么多指针?

public class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode curr = dummy;
        while(curr != null && curr.next != null && curr.next.next != null){
            ListNode tmp = curr.next.next.next; // tmp - 3
            curr.next.next.next = curr.next;    // 3 - 1
            curr.next = curr.next.next;         // 1 - 2
            curr.next.next.next = tmp;          // 3 - tmp
            curr = curr.next.next;              // 0 - 2
        }
        return dummy.next;
    }
}
Reverse Nodes in k-Group

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For example, Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5

分段反转 复杂度

时间 O(N) 空间 O(1)

思路

其实就是每K个节点执行一次反转链表,不过这里有几点要注意:

如果剩余节点不足K个则不执行反转,所以要先判断是否可以反转

为了拼接这个反转过后的链表,我们需要类似Reverse Linked List II一样的操作,即记录下该段链表的开头节点,这个开头节点的前一个节点,该链表的最后一个节点,和这最后一个节点的下一个节点。翻转后,开头节点就成了最后一个节点。

拆分成子函数,清晰易懂

K等于1的时候直接返回原链表

代码
public class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        if(k == 1) return head;
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode curr = dummy;
        while(curr != null && curr.next != null && curr.next.next != null){
            // 检测是否有足够节点供反转,不足直接退出
            if(!hasEnoughNodes(curr.next, k)) break;
            // 记录下第一个节点,反转后成为最后一个节点
            ListNode last = curr.next;
            // 从这第一个节点开始反转K个节点
            ListNode[] nodes = reverseK(last, k);
            // 将第0个节点的next接上新链表的头节点
            curr.next = nodes[0];
            // 将新链表的尾节点的后一个节点置为后一段链表的头节点
            last.next = nodes[1];
            // 准备反转下一段链表
            curr = last;
        }
        return dummy.next;
    }
    
    private boolean hasEnoughNodes(ListNode runner, int k){
        int remains = 0;
        while(runner != null && remains < k){
            remains++;
            runner = runner.next;
        }
        if(remains < k) return false;
        return true;
    }
    
    private ListNode[] reverseK(ListNode p1, int k){
        ListNode p2 = p1.next;
        // 反转K个节点
        while(p2 != null && k > 1){
            ListNode tmp = p2.next;
            p2.next = p1;
            p1 = p2;
            p2 = tmp;
            k--;
        }
        // 返回值第一个是新的链表头节点,第二个是下一段链表的头节点
        ListNode[] res = {p1, p2};
        return res;
    } 
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64686.html

相关文章

  • 【LC总结】翻转链表 Swap in Pairs, Reverse in k-Group, Reve

    摘要:注意这里,只要走到第位 Swap Nodes in Pairs For example,Given 1->2->3->4, you should return the list as 2->1->4->3. Solution public class Solution { public ListNode swapPairs(ListNode head) { if...

    Steve_Wang_ 评论0 收藏0
  • leetcode24 Swap Nodes in Pairs 交换链表中相邻两个节点

    摘要:题目要求翻译过来就是将链表中相邻两个节点交换顺序,并返回最终的头节点。思路这题的核心解题思路在于如何不占用额外的存储空间,就改变节点之间的关系。 题目要求 Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2->3->4, you should r...

    GT 评论0 收藏0
  • leetcode 24 Swap Nodes in Pairs

    摘要:最后返回头节点。同时题目要求只能占用常数空间,并且不能改变节点的值,改变的是节点本身的位置。翻转是以两个节点为单位的,我们新声明一个节点表示当前操作到的位置。每次操作结束,将指针后移两个节点即可。执行操作前要确定操作的两个节点不为空。 题目详情 Given a linked list, swap every two adjacent nodes and return its head....

    heartFollower 评论0 收藏0
  • leetcode 部分解答索引(持续更新~)

    摘要:前言从开始写相关的博客到现在也蛮多篇了。而且当时也没有按顺序写现在翻起来觉得蛮乱的。可能大家看着也非常不方便。所以在这里做个索引嘻嘻。顺序整理更新更新更新更新更新更新更新更新更新更新更新更新更新更新更新更新 前言 从开始写leetcode相关的博客到现在也蛮多篇了。而且当时也没有按顺序写~现在翻起来觉得蛮乱的。可能大家看着也非常不方便。所以在这里做个索引嘻嘻。 顺序整理 1~50 1...

    leo108 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<