請判斷乙個鍊錶是否為回文鍊錶。
示例 1:
輸入: 1->2
輸出: false
示例 2:
輸入: 1->2->2->1
輸出: true
高階:你能否用 o(n) 時間複雜度和 o(1) 空間複雜度解決此題?
這一題比較好弄的解法其實就是遍歷鍊錶然後將資料存到list裡面,之後判斷list裡面的資料是不是回文就好
/**
* definition for singly-linked list.
* public class listnode
* listnode(int val)
* listnode(int val, listnode next)
* }*/class
solution
int i =0;
int j = cur.
size()
-1;while
(i < j)
else
}return
true;}
}
但是這種方法的空間複雜度是不能達到要求的,看了題解直到是可以用快慢指標法找到鍊錶的中點,然後把中點以後的鍊錶反轉,直接比較反轉之後的鍊錶與前一半的鍊錶是否相同就可以判斷出來是不是回文鍊錶。
/**
* definition for singly-linked list.
* public class listnode
* listnode(int val)
* listnode(int val, listnode next)
* }*/class
solution
return
true;}
public listnode reverse
(listnode head)
return prev;
}public listnode fastslow
(listnode head)
return slow;
}}
思路
避免使用 o(n)o(n)o(n) 額外空間的方法就是改變輸入。
我們可以將鍊錶的後半部分反轉(修改鍊錶結構),然後將前半部分和後半部分進行比較。比較完成後我們應該將鍊錶恢復原樣。雖然不需要恢復也能通過測試用例,但是使用該函式的人通常不希望鍊錶結構被更改。
該方法雖然可以將空間複雜度降到 o(1)o(1)o(1),但是在併發環境下,該方法也有缺點。在併發環境下,函式執行時需要鎖定其他執行緒或程序對鍊錶的訪問,因為在函式執行過程中煉表會被修改。
演算法整個流程可以分為以下五個步驟:
找到前半部分鍊錶的尾節點。
反轉後半部分鍊錶。
判斷是否回文。
恢復鍊錶。
返回結果。
執行步驟一,我們可以計算鍊錶節點的數量,然後遍歷鍊錶找到前半部分的尾節點。
我們也可以使用快慢指標在一次遍歷中找到:慢指標一次走一步,快指標一次走兩步,快慢指標同時出發。當快指標移動到鍊錶的末尾時,慢指標恰好到鍊錶的中間。通過慢指標將鍊錶分為兩部分。
若煉表有奇數個節點,則中間的節點應該看作是前半部分。
步驟二可以使用「206. 反轉鍊錶」問題中的解決方法來反轉鍊錶的後半部分。
步驟三比較兩個部分的值,當後半部分到達末尾則比較完成,可以忽略計數情況中的中間節點。
步驟四與步驟二使用的函式相同,再反轉一次恢復鍊錶本身。
leetcode刷題 熱門百題 下乙個排列
實現獲取 下乙個排列 的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須 原地 修改,只允許使用額外常數空間。示例 1 輸入 nums 1,2,3 輸出 1,3,2 示例 2 輸入 nums 3,2,1 輸...
Leetcode刷題(9 回文數)
三.提交記錄 四.備註 判斷乙個整數是否是回文數。回文數是指正序 從左向右 和倒序 從右向左 讀都是一樣的整數。示例 1 輸入 121 輸出 true 示例 2 輸入 121 輸出 false 解釋 從左向右讀,為 121 從右向左讀,為 121 因此它不是乙個回文數。示例 3 輸入 10 輸出 f...
leetcode刷題總結 6 10題
六 zigzag conversion 本題屬於比較簡單的,很容易就能總結出規律。乙個zigzag數以2 numrows 2為乙個迴圈,每乙個豎行的字母下標為乙個cycle,除了第一行和最後一行,中間各行都要加乙個j cycle 2 i i為從零開始的行號,j為每個迴圈裡i cycle n.clas...