好久没写了。。。赶紧写一个
题目描述
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2 输出: false
示例 2:
输入: 1->2->2->1 输出: true
进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
解题思路
我的想法是,先遍历一遍,算出有多少个节点,申请一个数组,把所有数拷贝到数组里,再比较数组就很容易了,怎么样才能用O(1)的空间复杂度。。我没想出来,一会看看答案好了(可耻的我)。
代码
bool isPalindrome(struct ListNode* head) {
int iCount = 0;
struct ListNode *pstNode = head;
int *pBitmap = 0;
if (0 == head)
{
return true;
}
while (0 != pstNode)
{
iCount++;
pstNode = pstNode->next;
}
pBitmap = (int *)malloc(sizeof(int) * iCount);
pstNode = head;
for (int i = 0; i < iCount; i++)
{
pBitmap[i] = pstNode->val;
pstNode = pstNode->next;
}
for (int i = iCount/2 - 1; i >= 0; i--)
{
if (pBitmap[i] != pBitmap[iCount - i -1])
{
return false;
}
}
return true;
}
看答案
/**efinition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/* solve 1
bool isPalindrome(struct ListNode* head){
int len = 0;
int i = 0;
int j = 0;
int *tmpS = NULL;
struct ListNode* tmp = head;
if(head == NULL) {
return true;
}
while(tmp->next != NULL) {
tmp = tmp->next;
len++;
}
len++;
//printf("len is %d\n",len);
tmpS = (int*)malloc((len+1)*sizeof(int));
for(i=0; i<len; i++) {
tmpS[i] = head->val;
head = head->next;
}
for(j=0; j<(len)/2; j++) {
if(tmpS[j] != tmpS[len-j-1]) {
break;
}
}
//printf("\nj is %d\n",j);
return j==(len)/2 ? true :false;
}
*/
//solve 2
bool isPalindrome(struct ListNode* head){
struct ListNode* fast = head;
struct ListNode* slow = head;
struct ListNode* curr = NULL;
struct ListNode* next = NULL;
struct ListNode* tmp = NULL;
if(head == NULL || head->next == NULL) {
return true;
}
while(fast != NULL && fast->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
while(head != slow) {
next = head->next;
head->next = curr;
curr = head;
head = next;
}
/*
tmp = curr;
while(tmp != NULL) {
printf("%d,", tmp->val);
tmp = tmp->next;
}
*/
//fast指针一次移动两个,若为非空,即在移动指针时由fast->next为空跳出循环
//此时链表节点数为奇数个,应继续移动一个节点然后比较
if(fast != NULL) {
slow = slow->next;
}
while(slow != NULL) {
if(curr->val != slow->val) {
return false;
}
curr = curr->next;
slow = slow->next;
}
return true;
}
总结
原来是把链表前半个的顺序颠倒过来,然后再顺着转换完的顺序比较。入参的链表是可以改的啊。。。