第四節:鏈表相關(刪除倒數第N節點、相鄰位置交換)

一. 刪除倒數第N個節點

一. 題目描述

    給你一個鏈表,刪除鏈表的倒數第 n 個結點,並且返回鏈表的頭結點。

    示例:

    leetcode地址:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/

    難度:【中等】

二. 思路分析

     (經典的鏈表問題,雙指針(快慢指針)解決)

    (1).創建虛擬節點dummy, 即它的next指向head第一個節點 【主要爲了方便處理邊界情況,dummy是頭節點head的前一個節點】

    (2).創建快慢雙指針,等於dummy

    (3). 讓fast快指針先移動n+1步,然後讓fast和slow指針同時移動, 直到fast爲空  【精髓!】

        此時slow指針恰巧指向被刪除節點的前一個節點

    (4). 修改slow指針的指向,達到刪除的目的

    (5). 返回頭節點,即dummy.next

三. 代碼實操


class ListNode {
	val: number;
	next: ListNode | null;
	constructor(val?: number, next?: ListNode | null) {
		this.val = val === undefined ? 0 : val;
		this.next = next === undefined ? null : next;
	}
}

/**
 * 刪除鏈表倒數第N個節點
 * @param head 頭節點
 * @param n 需要被刪除的倒數第n個節點
 * @returns 返回頭節點
 */
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
	//1.創建虛擬節點
	let dummy = new ListNode(-1);
	dummy.next = head;

	//2.創建雙指針(快慢指針)
	let fast = dummy;
	let slow = dummy;

	//3.讓fast快指針移動n+1步
	for (let i = 0; i <= n; i++) {
		fast = fast.next!;
	}

	//4.讓fast和slow指針同時移動,直到fast爲空(即超過了最後一個元素)
	while (fast) {
		fast = fast.next!;
		slow = slow.next!;
	}

	//5.此時slow指針恰巧指向被刪除節點的前一個節點
	slow.next = slow.next?.next!;

	//6.返回頭節點
	return dummy.next;
}

 

 

二. 鏈表相鄰位置兩兩交換

一. 題目描述

 給你一個鏈表,兩兩交換其中相鄰的節點,並返回交換後鏈表的頭節點。你必須在不修改節點內部的值的情況下完成本題(即,只能進行節點交換)。

 leetcode:https://leetcode.cn/problems/swap-nodes-in-pairs/description/

 難度:【中等】

二. 思路分析

(1). 創建虛擬節點dummy節點,指向head節點

(2). 創建一個current節點,默認指向虛擬節點(這裏因爲有虛擬節點,所以可以直接調用next)

(3). 遍歷節點(接下來兩個節點都存在,一直循環)

      A. 取出接下來的兩個節點

      B. 交換位置

      C. current賦值,開始下一輪循環

(4).返回頭節點

 

三. 代碼實操


class ListNode {
	val: number;
	next: ListNode | null;
	constructor(val?: number, next?: ListNode | null) {
		this.val = val === undefined ? 0 : val;
		this.next = next === undefined ? null : next;
	}
}

/**
 * 鏈表相鄰位置的兩兩交換
 * @param head 頭節點
 * @returns  頭節點
 */
function swapPairs(head: ListNode | null): ListNode | null {
	// 1. 創建虛擬節點
	let dummy = new ListNode(-1);
	dummy.next = head;

	//2. 創建current節點,指向虛擬節點
	let current = dummy;

	//3. 循環進行兩兩交換
	while (current.next && current.next.next) {
		let node1 = current.next;
		let node2 = current.next.next;

		//交換node1和node2位置
		current.next = node2;
		node1.next = node2.next;
		node2.next = node1;

		//開始下一次交換
		current = node1;
	}

	return dummy.next;
}

 

 

三. 

 

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鵬飛)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 聲     明1 : 如有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲     明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章