#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;
/*
问题:
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?
分析:给定单链表,能否在O(n)时间和O(1)空间确定其是否是回文的。
有点类似于之前的逆置链表,直接可以将第一个和最后一个进行比较,
但是逆置是本质上是头插法+拆分链表,此题仅需要每次获得最后一个结点,然后与
链表头部进行比较。
还有一个方法就是先逆置链表,然后逐一比较。但是原来的链表都不在了。
难道能边逆置边比较
举例:
1 2 3 4 5
初始新结点为空:找到下一个一个结点2, 2->,原来链表:1 ,2->3->4,比较
2->1,接下来找到4与2表,4->5->NULL
leecode解法:https://leetcode.com/problems/palindrome-linked-list/?tab=Solutions
快慢指针,来确定中点,然后逆置后面半段链表,牛逼。
考虑到不能使用额外的空间,则需要使用逆置。
逆置:下一个结点插入到当前结点的头部,典型的头插法。另外空链表算回文应该
输入:
5
1 2 3 2 1
4
1 2 2 1
5
1 3 2 2 1
4
1 2 3 1
2
1 2
2
1 1
1
1
输出:
true
true
false
false
false
true
true
1 2 3 4
slow:1,fast:1,fast:3,slow:2,fats:NULL , slow:3
1 2 3 4 5
slow:1,fast:1,fast:3,slow:2,fast:5,fast->next:NULL ,slow:3
slow结点前面部分逆置
由于slow偏后,将slow及其之后部分逆置即可,然后与头部比较
关键:
1 快慢指针,来确定中点,然后逆置后面半段链表,牛逼。
考虑到不能使用额外的空间,则需要使用逆置。
逆置:下一个结点插入到当前结点的头部,典型的头插法。另外空链表算回文应该
2 由于slow偏后,将slow及其之后部分逆置即可,然后与头部比较
*/
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(!head || NULL == head->next)
{
return true;
}
ListNode* slow = head;
ListNode* fast = head;
ListNode* previous = NULL;
while(fast && fast->next)
{
previous = slow;
slow = slow->next;
fast = fast->next->next;
}
//将后面半段逆置
ListNode* newHead = reverseList(slow);
ListNode* newNode = newHead;
ListNode* node = head;
bool isPal = true;
while(newNode && node)
{
if(newNode->val != node->val)
{
isPal = false;
break;
}
newNode = newNode->next;
node = node->next;
}
//再次逆置,将链表恢复原状
newHead = reverseList(newHead);
if(previous)
{
previous->next = newHead;
}
return isPal;
}
ListNode* reverseList(ListNode* head)
{
if(!head || NULL == head->next)
{
return head;
}
ListNode* next = NULL;
ListNode* newHead = NULL;
//头插法来逆置
while(head)
{
next = head->next;
head->next = newHead;
newHead = head;
head = next;
}
return newHead;
}
};
void print(ListNode* head)
{
if(!head)
{
cout << "no result" << endl;
}
ListNode* tempHead = head;
while(head)
{
cout << head->val << " ";
head = head->next;
}
cout << endl;
head = tempHead;
}
ListNode* buildList(vector<int>& nums)
{
if(nums.empty())
{
return NULL;
}
int size = nums.size();
ListNode* head ;
ListNode *tail;
ListNode* node;
for(int i = 0 ; i < size ; i++)
{
if(i)
{
node = new ListNode(nums.at(i));
tail->next = node;
tail = node;
}
else
{
head = new ListNode(nums.at(i));
tail = head;
}
}
return head;
}
void deleteList(ListNode* head)
{
ListNode* node;
while(head)
{
node = head->next;
delete head;
head = node;
}
}
void process()
{
vector<int> nums;
int value;
int num;
Solution solution;
vector<int> result;
while(cin >> num )
{
nums.clear();
for(int i = 0 ; i < num ; i++)
{
cin >> value;
nums.push_back(value);
}
ListNode* head = buildList(nums);
bool answer = solution.isPalindrome(head);
if(answer)
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
print(head);
deleteList(head);//删除节点了
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
leecode 解题总结:234. Palindrome Linked List
最新推荐文章于 2023-02-21 05:16:30 发布