您的位置:首页 > Web前端 > Node.js

(Java) LeetCode 24. Swap Nodes in Pairs —— 两两交换链表中的节点

2018-07-08 10:50 645 查看

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永远是结果的首节点
}
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: