《Cracking the Coding Interview程式設計師面試金典》----迴文連結串列

塵封的記憶0發表於2017-04-28
時間限制:3秒 空間限制:32768K 熱度指數:2977
本題知識點: 程式設計基礎 連結串列
 演算法知識視訊講解

題目描述

請編寫一個函式,檢查連結串列是否為迴文。

給定一個連結串列ListNode* pHead,請返回一個bool,代表連結串列是否為迴文。

測試樣例:
{1,2,3,2,1}
返回:true
{1,2,3,2,3}

返回:false

思路:題目描述是這樣的,需要判斷一個給定的連結串列是否為迴文連結串列,若給定連結串列如{1,2,3,2,1}則返回true,反之返回false。想法應該說並不難,但是我在連結串列的地址和賦值之間來回徘徊了很久才大概明白程式碼測試一直不能通過是因為什麼。首先定義了兩個連結串列節點分別指向第一個給定節點和NULL,然後遍歷給定的連結串列將連結串列反轉。在遍歷的過程中,將reverse這個想象中是反轉後的連結串列先傳給一個temp以做保留,將reverse指向遍歷當前的節點,而reverse->next指向先前的地址也就是temp,然而此時我想也就破壞了給定連結串列指向next的這個節點連結了。以我的專業出身和智商還沒有真正深究出原因,不過我猜想是因為永遠指向同一個地址那麼比較的時候肯定會不如人意,當在反轉時有必要將反轉之後的連結串列reverse和在遍歷當前給定連結串列的時候new一個新的ListNode而不是在同一條地址鏈上進行多次的重複操作以至於最後比對的original連結串列丟失。這也是為什麼當只是單純做反轉連結串列的時候遍歷第一步就要儲存好當前節點next指向的地址。所以重新定義並new一個連結串列reverse為NULL,然後遍歷整個給定的連結串列,將當前節點值給該次迴圈中的reverse節點,將該被改動的reverse節點的next指向上一迴圈中的reverse節點,以此類推,直到把NULL推到最後一個位置。這個方法我很熟悉,跟做硬體編譯時傳輸10101010....類的資料相差不大,都是按照一定的順序你推我我推你到窮盡。好吧,下面來貼上糾結了我一下午的最終通過程式碼示例:

/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
	bool isPalindrome(ListNode* pHead) {
		// write code here
		ListNode* temp = NULL;
		ListNode* current = pHead;
		ListNode* reverse = new ListNode(NULL);
		if (pHead == NULL)
			return false;
		while (current){
			//temp = reverse;
			//reverse->next = temp;
			//reverse = current->next;
			temp = reverse;
			ListNode* nextnode = new ListNode(current->val);//reverse = current->next;
			reverse = nextnode;
			reverse->next = temp;
			current = current->next;
		}

		while (pHead){
			if (pHead->val != reverse->val)
			{
				return false;
				break;
			}

			pHead = pHead->next;
			reverse = reverse->next;
		}
		return true;
	}
};

不懂的可以加我的QQ群:261035036(IT程式設計師面試寶典

群) 歡迎你到來哦,看了博文給點腳印唄,謝謝啦~~




相關文章