題目如下:
請判斷乙個鍊錶是否為回文鍊錶。
示例 1:
輸入: 1->2
輸出: false
示例 2:
輸入: 1->2->2->1
輸出: true
高階:你能否用 o(n) 時間複雜度和 o(1) 空間複雜度解決此題?
思路一:
首先讀題,不考慮高階情況的話,由於回文鍊錶的數值是對稱的。
因此,我們可以遍歷一遍輸入的鍊錶,宣告兩個空的vector 分別為left和right,每讀取乙個值,將節點的node->val在left的左邊插入,在right的右邊插入。
可以想得到,我們得到的right的順序和鍊錶的數值的順序是一樣的;而left的數值的順序和鍊錶的數值順序相反。
由於回文鍊錶的數值對稱,因此,如果我們最終得到的兩個vector是相等的話,則這個鍊錶是回文鍊錶。
這樣做的只用了一次遍歷,時間複雜度是o(n),但是用了兩個長度為n的vector,因此空間複雜度為o(n)。
解答**如下:
class solution
vector<
int> left;
vector<
int> right;
while
(head)
return left == right;}}
;
思路二:
我們之前用的方法時間複雜度達到了要求,但是空間複雜度不符合高階的要求。
我之前做過反轉鍊錶的題目,於是想到,首先設定乙個first節點,指向煉表表頭;
然後遍歷一次得到鍊錶長度count,然後從鍊錶的(count + 1)/2的地方開始,反轉鍊錶(也就是說將鍊錶的後半部分反轉,奇數鍊錶的話反轉過後後半部分少乙個節點,比如,五個節點的鍊錶,前面三個節點,後面兩個節點);反轉之後得到原本鍊錶尾巴上的節點,將頭結點和尾節點同時開始遍歷,即可判斷出結果。
這一思路,一共用了三個listnode指標,空間複雜度為o(1);一共遍歷四次,時間複雜度為o(n),符合高階要求。
**如下:
/**
* definition for singly-linked list.
* struct listnode
* };
*/class solution
listnode* first = new listnode(0
);first = head;
int count =1;
while
(head->next)
head = first;
count =
(count +1)
/2;while
(count >0)
// head = first;
listnode* pre;
listnode* pnext;
pre =
null
;// cout << head->val << endl;
while
(head->next)
head->next = pre;
while
(head)
head = head->next;
first = first->next;
}// delete first;
return true;}}
;
這裡遇到了乙個問題,就是不注釋delete的話會報錯,報錯資訊為:double free or corruption (out)。
感覺要**還是可以繼續改得簡潔一點,不過感覺這樣**挺好讀懂的,希望各位大佬批評指正,提出一下更好的思路。
Leetcode C 回文鍊錶
1.題目 請判斷乙個鍊錶是否為回文鍊錶。示例 1 輸入 1 2輸出 false示例 2 輸入 1 2 2 1輸出 true2.code definition for singly linked list.struct listnode class solution if n 1 n 0 return...
LeetCode C 環形鍊錶
給定乙個鍊錶,判斷鍊錶中是否有環。為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置 索引從 0 開始 如果 pos 是 1,則在該鍊錶中沒有環。示例 1 輸入 head 3,2,0,4 pos 1 輸出 true 解釋 鍊錶中有乙個環,其尾部連線到第二個節點。示例 2 輸...
LeetCode C 相交鍊錶
編寫乙個程式,找到兩個單鏈表相交的起始節點。如下面的兩個鍊錶 在節點 c1 開始相交。示例 1 輸入 intersectval 8,lista 4,1,8,4,5 listb 5,0,1,8,4,5 skipa 2,skipb 3 輸出 reference of the node with valu...