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;
}