1. 程式人生 > 其它 >LeetCode234.迴文連結串列

LeetCode234.迴文連結串列

題目

給你一個單鏈表的頭節點 head ,請你判斷該連結串列是否為迴文連結串列。如果是,返回 true ;否則,返回 false 。

示例 1:
輸入:head = [1,2,2,1]
輸出:true

示例 2:
輸入:head = [1,2]
輸出:false


提示:

連結串列中節點數目在範圍[1, 105] 內
0 <= Node.val <= 9

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/palindrome-linked-list
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

解題方法

將值複製到陣列中後用雙指標

1.複製連結串列的值到陣列中
2.使用雙指標判斷是否為迴文

時間複雜度:O(n)空間複雜度:O(n)

遞迴

 時間複雜度:O(n)空間複雜度:O(n)

快慢指標

1.找到前半部分連結串列的位節點
2.反轉後半部分連結串列
3.判斷是否迴文
4.恢復連結串列
5.返回結果

時間複雜度:O(n)空間複雜度:O(1)

程式碼

type ListNode struct {
	Val int
	Next *ListNode
}

// 陣列+雙指標
func isPalindrome(head *ListNode) bool {
	vals := []int{}
	// 遍歷一遍節點值新增到陣列
	for ;head != nil;head  = head.Next{
		vals = append(vals,head.Val)
	}
	n := len(vals)
	// 雙指標從頭和尾比較
	for i,v := range vals[:n/2]{
		if v != vals[n-1-i]{
			return false
		}
	}
	return true
}

// 遞迴
func isPalindrome2(head *ListNode) bool {
	frontPointer := head
	var recursivelyCheck func(node *ListNode) bool
	recursivelyCheck = func(node *ListNode) bool {
		if node != nil{
			if !recursivelyCheck(node.Next){
				return false
			}
			if node.Val != frontPointer.Val{
				return false
			}
			frontPointer = frontPointer.Next
		}
		return true
	}
	return recursivelyCheck(head)
}


// 反轉連結串列
func reversList(head *ListNode) *ListNode {
	var prev,cur *ListNode = nil,head
	for cur != nil{
		nextTmp := cur.Next
		cur.Next = prev
		prev = cur
		cur = nextTmp
	}
	return prev
}

// 快慢指標找到前半部分連結串列尾節點
func endOfFirstHalf(head *ListNode) *ListNode {
	fast,slow := head,head
	// 快指標速度為慢指標兩倍,快指標走到盡頭,慢指標走一半
	for fast.Next != nil && fast.Next.Next != nil{
		fast = fast.Next.Next
		slow = slow.Next
	}
	return slow
}

// 快慢指標
func isPalindrome3(head *ListNode) bool {
	if head == nil{
		return true
	}
	// 獲取前半部分連結串列尾節點
	firstHalfEnd := endOfFirstHalf(head)
	// 反轉後半部分節點
	secondHalfStart := reversList(firstHalfEnd.Next)

	// 與反轉後的後半部分連結串列比較判斷是否是迴文
	p1,p2 := head,secondHalfStart
	result := true
	for result && p2 != nil{
		if p1.Val != p2.Val{
			result = false
		}
		p1 = p1.Next
		p2 = p2.Next
	}
	// 還原連結串列反轉
	firstHalfEnd.Next = reversList(secondHalfStart)
	return result
}