[算法]鏈表題目

兩兩交換鏈表中的節點

題目描述

給定一個鏈表,兩兩交換其中相鄰的節點,並返回交換後的鏈表。java

你不能只是單純的改變節點內部的值,而是須要實際的進行節點交換。node

 

示例:網絡

給定 1->2->3->4, 你應該返回 2->1->4->3.spa

來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/swap-nodes-in-pairs
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。code

思路

先提供一個投機取巧的辦法,既然轉換鏈表中的先後關係比較麻煩,那我不妨反其道而行之,我直接交換鏈表的值,讓鏈表的關係保持不變便可。blog

還有一種思路是經過遞歸來計算。遞歸

代碼

解法1:leetcode

/**
 * Definition for singly-linked list.
 * class ListNode(var _x: Int = 0) {
 *   var next: ListNode = null
 *   var x: Int = _x
 * }
 */
object Solution {
    def swapPairs(head: ListNode): ListNode = {
        var newHead = head
        while(newHead != null && newHead.next != null){
            val temp = newHead.x
            newHead.x = newHead.next.x
            newHead.next.x = temp
            newHead = newHead.next.next
        }
        head
    }
}

解法2:get

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode next = head.next;
        head.next = swapPairs(next.next);
        next.next = head;
        return next;
    }
}

反轉鏈表II

題目描述

反轉從位置 m 到 n 的鏈表。請使用一趟掃描完成反轉。it

說明:
1 ≤ m ≤ n ≤ 鏈表長度。

示例:

輸入: 1->2->3->4->5->NULL, m = 2, n = 4
輸出: 1->4->3->2->5->NULL

來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/reverse-linked-list-ii
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。

思路

同上,投機取巧的辦法只須要交換值便可,用一個棧來臨時存儲數據。

也能夠參考以前反轉鏈表的思路,將鏈表分紅三段,m以前的,m到n的,n以後的。

代碼

解法1(掃描了2次,不太符合要求):

/**
 * Definition for singly-linked list.
 * class ListNode(var _x: Int = 0) {
 *   var next: ListNode = null
 *   var x: Int = _x
 * }
 */
import java.util.Stack
object Solution {
    def reverseBetween(head: ListNode, m: Int, n: Int): ListNode = {
        var newHead = head
        var index = 1
        val stack: Stack[Int] = new Stack[Int]()
        while(newHead != null){
          if(index >= m && index <= n){
            stack.push(newHead.x)
          }
          newHead = newHead.next
          index += 1
        }

        newHead = head
        index = 1
        while(newHead != null){
          if(index >= m && index <= n){
            newHead.x = stack.pop()
          }
          newHead = newHead.next
          index += 1
        }
        head
    }
}

解法2:

class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode cur = head, pre = dummy;
        int i = 1;
        while (i < m) {//經過i去尋找開始反轉的地方
            pre = cur;
            cur = cur.next;
            i++;
        }
        ListNode node = pre;//node記錄的是反轉鏈表的前一個節點

        //反轉從m到n的鏈表,解法同206題
        while (i <= n) {
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
            i++;
        }

        //反轉鏈表接回原鏈表
        node.next.next = cur;
        node.next = pre;
        return dummy.next;

    }
}

解釋下子鏈表怎麼接回原鏈表:

1->2->3->4->5->null, m = 2, n = 4,

子鏈表反轉完成後是這樣的

1<->2<-3<-4 5->null,此時cur = 5, pre = 4, node = 1,接下來就顯而易見了。

https://leetcode-cn.com/problems/reverse-linked-list-ii/solution/fan-zhuan-lian-biao-ii-by-leetcode/

相關文章
相關標籤/搜索