zoukankan      html  css  js  c++  java
  • (Java) LeetCode 24. Swap Nodes in Pairs —— 两两交换链表中的节点

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

    Example:

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

    Note:

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

    本题是两个一组翻转链表,类似LeetCode 206. Reverse Linked List —— 反转链表又略有不同。思路其实是一样的,还是想两种方法来做,迭代和递归。

    解法一,迭代:

    遍历链表,一个一个的去交换前驱和后继节点。类似206,本题也要建立一个假节点去链接链表头,因为除非是单节点链表,否则原链表头一定不会是结果的链表头。用假节点去链接结果会更容易操作和理解。建立指针pre指向将要翻转的两个节点的前驱,如果pre.next和pre.next.next同时存在,那么就翻转对应节点。翻转的时候建立一些临时节点存储数据会使整个过程很清晰,详见代码。

    解法二,迭代:

    思路和206几乎一样。输入规模最小的问题即空链表和单节点链表,直接返回表头即可。当我们要处理k个节点的链表的时候,可以先处理k-2节点的子问题。之所以是k-2是因为每次都要处理成对的两个节点,所以递归要从成对后的第三个节点开始。递归返回的结果是已经翻转完成后的链表的首节点,那么如果把这个首节点的两个前驱对换,再把递归返回来的结果连在第一个前驱后面,即可完成整个k节点的翻转。详见代码注释。


    解法一(Java)

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode swapPairs(ListNode head) {
            ListNode preHead = new ListNode(0);
            preHead.next = head;
            ListNode pre = preHead;
            while (pre.next != null && pre.next.next != null) {
                ListNode first = pre.next;
                ListNode second = first.next;
                ListNode third= second.next;
                pre.next = second;
                second.next = first;
                first.next = third;
                pre = pre.next.next;
            }
            return preHead.next;
        }
    }

    解法二(Java)

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode swapPairs(ListNode head) {
            if (head == null || head.next == null) return head; 
            ListNode second = head.next; //存储第二个节点在second中
            head.next = swapPairs(second.next); //要递归处理second节点后的那个节点,并将翻转好的结果链接到second的前驱后,即head
            second.next = head; //再将second的前驱连在second后,完成翻转
            return second; //翻转后,second永远是结果的首节点
        }
    }
  • 相关阅读:
    adodb.stream文件操作类详解
    Html中Label标记的作用和使用介绍
    正则表达式的威力轻松消除HTML代码
    只需一行代码就能让IE 6崩溃
    码农干货系列【17】Wind.js与Promise.js
    码农干货系列【3】割绳子(cut the rope)制作点滴:旋转(rotation)
    HTML5 Canvas开发者和读者的福音
    码农干货系列【8】世界上最简单的3D渲染(no webgl)
    码农干货系列【18】getting started with Promise.js(总)
    ProgressForm
  • 原文地址:https://www.cnblogs.com/tengdai/p/9279427.html
Copyright © 2011-2022 走看看