編寫一個函數,檢查輸入的鏈表是不是迴文的。如圖:面試
試題連接:https://leetcode-cn.com/problems/palindrome-linked-list-lcci/算法
看到該題,首先想打到的就是使用本身最拿手的語言java來作。首先,咱們先來觀查題目所給鏈表的結構:數組
class ListNode { int val; ListNode next; ListNode(int x) { val = x; } }
因爲題目中要求判斷一個鏈表是否迴文,所以很天然的一個想法就是,將鏈表變量,取出其中的值,放在一個有序的容器中。在java中很天然的就想到了list集合,因而就有了下述的解法:數據結構
public static boolean isPalindrome(ListNode head) { List list = new ArrayList(); //定義一個輔助指針,用來遍歷鏈表 ListNode pCurrent = head; //當鏈表不爲null時,就一直循環 while (pCurrent != null) { //將該數保存到數組中 list.add(pCurrent.val); pCurrent = pCurrent.next; } //遍歷集合,看首尾是否相等 for(int i = 0;i < list.size() / 2;i++) { if(!list.get(i).equals(list.get(list.size() - i - 1))) { return false; } } return true; }
算法效果:函數
能夠看出,該算法在java的提交記錄中,時間稍微較慢,當時所須要的內存確實最少的。然而,計算機程序比較關心的是算法的執行效率,所以該算法還得進行改進。測試
因爲上述的算法的執行時間太長,猜測是否是由於使用了List集合而致使的。可是,若是不適用集合,咱們的先獲取到該鏈表的長度,而後定義一個大小剛剛適合的數組。代碼以下:3d
public static boolean isPalindrome(ListNode head) { //定義一個輔助指針,用來遍歷鏈表 ListNode pCurrent = head; //當鏈表不爲null時,就一直循環 int count = 0; while (pCurrent != null) { //計數 count++; pCurrent = pCurrent.next; } //再來一論,裝進數組 pCurrent = head; int[] arr = new int[count]; for(int i = 0;i < count;i++) { arr[i] = pCurrent.val; pCurrent = pCurrent.next; } //遍歷集合,看首尾是否相等 for(int i = 0;i < count / 2;i++) { if(arr[i] != arr[count - i - 1]) { return false; } } return true; }
算法效果:指針
能夠看出,用數組代替集合,增長一次循環後的效率獲得大幅度的提高。code
奈何,博主目前仍是一個本科大學生,在數據結構與算法這門課上垂死掙扎,而考試只容許用C來做答,所以,只有用C語言重寫上述的java算法。
struct ListNode { int val; struct ListNode *next; };
接下來,用C語言來實現上述的java題解二:
bool isPalindrome(struct ListNode* head){ //定義一個輔助指針,用來遍歷鏈表 struct ListNode* pCurrent = head; //當鏈表不爲null時,就一直循環 int count = 0; while (pCurrent != NULL) { //計數 count++; pCurrent = pCurrent->next; } if(count == 0) return true; //再來一論,裝進數組 pCurrent = head; int arr[count]; for(int i = 0;i < count;i++) { arr[i] = pCurrent->val; pCurrent = pCurrent->next; } //遍歷集合,看首尾是否相等 for(int i = 0;i < count / 2;i++) { if(arr[i] != arr[count - i - 1]) { return false; } } return true; }
算法效果:
由執行用時能夠看出,在C語言的解法中,該算法並非最優解。
除此以外,還有另一種思路,就是將鏈表拆分紅兩部分,而後使得一部分反轉,後遍歷兩個鏈表,觀察是否相等。可是,該方法通過博主測試後,發現其效率還不如上述解法高效,所以不在敘述,後續若是有新的更高效解法在來敘述。