Palindrome Linked List
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
palindrome: n.迴文(正反讀都一樣的詞語)
題目意思較簡單,我就不翻譯了.
原題鏈接: https://leetcode.com/problems/palindrome-linked-list/
編程想法很簡單,也比較笨.就是遍歷一次鏈表,然後創建一個反向的鏈表,再逐一比較即可.其中有兩次循環,算法時間複雜度應該是O(n).但空間複雜度也是O(n).
如何做到O(1)的空間複雜度還沒有想到.
其中涉及到一個問題, 我印象中, 頭結點不是第一個節點,頭結點的下一個節點,纔是第一個數據節點.所以調試了兩種版本.編程環境是VS,附帶調試代碼.
版本一: 頭結點是第一個數據節點
// Definition for singly-linked list.
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* createList(int* vals, int size) {
if ((0 >= size) || (NULL == vals)) {
return NULL;
}
struct ListNode* head = (struct ListNode*) malloc(sizeof(struct ListNode));
struct ListNode* next = head;
head->next = NULL;
head->val = vals[0];
for (int i = 1; i < size; ++i) {
next->next = (struct ListNode*) malloc(sizeof(struct ListNode));
next->next->val = vals[i];
next->next->next= NULL;
next = next->next;
}
return head;
}
struct ListNode* reverseList(struct ListNode* head) {
if (NULL == head) {
return NULL;
}
struct ListNode* revHead = (struct ListNode*) malloc(sizeof(struct ListNode));
struct ListNode* revNext = NULL;
struct ListNode* tmp = head;
while (NULL != tmp) {
revHead = (struct ListNode*) malloc(sizeof(struct ListNode));
revHead->val = tmp->val;
revHead->next= revNext;
revNext = revHead;
tmp = tmp->next;
}
return revHead;
}
void freeList(struct ListNode* head) {
struct ListNode* tmp = head;
while (NULL != head) {
tmp = head->next;
free(head);
head = tmp;
}
}
bool isPalindrome(struct ListNode* head) {
if (NULL == head) {
return false;
}
struct ListNode* revList = reverseList(head);
struct ListNode* tmp1 = head;
struct ListNode* tmp2 = revList;
while (NULL != tmp1->next) {
tmp1 = tmp1->next;
tmp2 = tmp2->next;
if (tmp2->val != tmp1->val) {
freeList(revList);
return false;
}
}
freeList(revList);
return true;
}
int _tmain(int argc, _TCHAR* argv[]) {
char c = 'Y';
while (('Y' == c) || ('y' == c)) {
int size = -1;
cout << "size: ";
cin >> size;
int* Array = (int*) malloc(size * sizeof(int));
memset(Array, '\0', size * sizeof(int));
for (int i = 0; i < size; ++i) {
cout << "The " << i + 1 << "th " << "number: ";
cin >> Array[i];
}
cout << isPalindrome(createList(Array, size)) << endl;
cout << "Continue(Y/N)? ";
cin >> c;
}
return 0;
}
版本二: 頭結點非第一個數據節點, 就其中兩個函數不一樣
// Definition for singly-linked list.
struct ListNode {
int val;
struct ListNode *next;
};
/*
* 頭結點非第一個節點. */
struct ListNode* createList(int* vals, int size) {
if ((0 >= size) || (NULL == vals)) {
return NULL;
}
struct ListNode* head = (struct ListNode*) malloc(sizeof(struct ListNode));
struct ListNode* next = head;
for (int i = 0; i < size; ++i) {
next->next = (struct ListNode*) malloc(sizeof(struct ListNode));
next->next->val = vals[i];
next->next->next= NULL;
next = next->next;
}
return head;
}
struct ListNode* reverseList(struct ListNode* head) {
if (NULL == head) {
return NULL;
}
struct ListNode* revHead = (struct ListNode*) malloc(sizeof(struct ListNode));
struct ListNode* revNext = revHead;
struct ListNode* tmp = head;
revHead->next = NULL;
while (NULL != tmp->next) {
tmp = tmp->next;
revHead = (struct ListNode*) malloc(sizeof(struct ListNode));
revNext->val = tmp->val;
revHead->next= revNext;
revNext = revHead;
}
return revHead;
}
void freeList(struct ListNode* head) {
struct ListNode* tmp = head;
while (NULL != head) {
tmp = head->next;
free(head);
head = tmp;
}
}
bool isPalindrome(struct ListNode* head) {
if (NULL == head) {
return false;
}
struct ListNode* revList = reverseList(head);
struct ListNode* tmp1 = head;
struct ListNode* tmp2 = revList;
while (NULL != tmp1->next) {
tmp1 = tmp1->next;
tmp2 = tmp2->next;
if (tmp2->val != tmp1->val) {
freeList(revList);
return false;
}
}
freeList(revList);
return true;
}
int _tmain(int argc, _TCHAR* argv[]) {
char c = 'Y';
while (('Y' == c) || ('y' == c)) {
int size = -1;
cout << "size: ";
cin >> size;
int* Array = (int*) malloc(size * sizeof(int));
memset(Array, '\0', size * sizeof(int));
for (int i = 0; i < size; ++i) {
cout << "The " << i + 1 << "th " << "number: ";
cin >> Array[i];
}
cout << isPalindrome(createList(Array, size)) << endl;
cout << "Continue(Y/N)? ";
cin >> c;
}
return 0;
}