問題描述
請判斷乙個鍊錶是否為回文鍊錶。鍊錶為單向無環鏈表
示例 1:
輸入: 1->2輸出: false示例 2:
輸入: 1->2->2->1輸出: true反轉後半部分鍊錶
這題是讓判斷鍊錶是否是回文鍊錶,所謂的回文鍊錶就是以鍊錶中間為中心點兩邊對稱。我們常見的有判斷乙個字串是否是回文字串,這個比較簡單,可以使用兩個指標,乙個最左邊乙個最右邊,兩個指標同時往中間靠,判斷所指的字元是否相等。
但這題判斷的是鍊錶,因為這裡是單向鍊錶,只能從前往後訪問,不能從後往前訪問,所以使用判斷字串的那種方式是行不通的。但我們可以通過找到鍊錶的中間節點然後把鍊錶後半部分反轉(關於鍊錶的反轉可以看下432,劍指 offer-反轉鍊錶的3種方式),最後再用後半部分反轉的鍊錶和前半部分乙個個比較即可。這裡以示例2為例畫個圖看一下。
最後再來看下**
public boolean ispalindrome(listnode head)
//如果fast不為空,說明鍊錶的長度是奇數個
if (fast != null)
//反轉後半部分鍊錶
slow = reverse(slow);
fast = head;
while (slow != null)
return true;
}//反轉鍊錶
public listnode reverse(listnode head)
return prev;
}
使用棧解決我們知道棧是先進後出的一種資料結構,這裡還可以使用棧先把鍊錶的節點全部存放到棧中,然後再乙個個出棧,這樣就相當於鍊錶從後往前訪問了,通過這種方式也能解決,看下**
public boolean ispalindrome(listnode head)
//然後再出棧
while (head != null)
head = head.next;
}return true;
}
這裡相當於鍊錶從前往後全部都比較了一遍,其實我們只需要拿鍊錶的後半部分和前半部分比較即可,沒必要全部比較,所以這裡可以優化一下
public boolean ispalindrome(listnode head)
//len長度除以2
len >>= 1;
//然後再出棧
while (len-- >= 0)
return true;
}
遞迴方式解決我們知道,如果對鍊錶逆序列印可以這樣寫
private void printlistnode(listnode head)
也就是說最先列印的是鍊錶的尾結點,他是從後往前列印的,看到這裡是不是有靈感了,我們來對上面的對面進行改造一下
listnode temp;
public boolean ispalindrome(listnode head)
private boolean check(listnode head)
問題分析回文鍊錶的判斷,相比回文字串的判斷稍微要麻煩一點,但難度也不是很大,如果對鍊錶比較熟悉的話,這3種解決方式都很容易想到,如果不熟悉的話,可能最容易想到的就是第2種了,也就是棧和鍊錶的結合。
如果對棧和鍊錶不熟悉的話,可以看下352,資料結構-2,鍊錶,這裡詳細介紹了單向鍊錶,雙向鍊錶,以及環形鍊錶的斷開和連線。也可以看下363,資料結構-4,棧,這裡有對棧的一些簡單介紹和例項講解。
鍊錶回文判斷
判斷一條單向鍊錶是不是 回文 回文,英文palindrome,指順著讀和反過來讀都一樣。判斷回文單向鍊錶跟判斷回文字串很大的區別就是遍歷。字串可以自由向前遍歷,而單向字串不行,因此最簡單直觀的思路就是將鍊錶翻轉,然後再進行比較。但是這種方法就比較笨,因為還需要建立另外乙個單鏈表來儲存原有的單鏈表,然...
判斷回文鍊錶
請判斷乙個鍊錶是否為回文鍊錶。鍊錶為單向無環鏈表 示例 1 輸入 1 2 輸出 false 示例 2 輸入 1 2 2 1 輸出 true 這題是讓判斷鍊錶是否是回文鍊錶,所謂的回文鍊錶就是以鍊錶中間為中心點兩邊對稱。我們常見的有判斷乙個字串是否是回文字串,這個比較簡單,可以使用兩個指標,乙個最左邊...
判斷鍊錶是否回文?
given a singly linked list,determine if it is a palindrome.思路 兩個指標,乙個正常遞推,另乙個遞推速度為第乙個的兩倍 node.next.next 到末,分兩種情況 1.奇數個元素,最後快指標指向最後乙個元素 p2.next null 2....