Leetcode 234:回文链表
题目描述
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
我的解法
利用map,做两次循环,第一次循环把链表的val存进map中,第二次循环遍历map,检验map存的元素是否回文。
bool isPalindrome(ListNode* head) {
map<int, int> m;
ListNode* cur = head;
int i = 0;
while(cur)
{
m[i] = cur->val;
cur = cur->next;
i++;
}
for(int j = 0; j < i/2; j ++)
{
if(m[j] != m[i-1-j])
{
return false;
}
}
return true;
}
利用stack先入后出
因为stack是先入后出,所以存进stack之后pop的顺序是反过来的,直接遍历链表比较是否相等即可。
bool isPalindrome(ListNode* head) {
stack<int> st;
ListNode* cur = head;
while(cur)
{
st.push(cur->val);
cur = cur->next;
}
cur = head;
while(cur)
{
if(head->val != st.top())
{
return false;
}
st.pop();
cur = cur->next;
head = head->next;
}
return true;
}
快慢指针+stack
上面的stack解法中,在遍历循环中重复比较了一半的节点,在遍历入栈时其实并不需要后半段的节点,因此可利用快慢指针思想,找到链表中点即可,然后拿链表剩下的节点与出栈元素比较。
bool isPalindrome(ListNode* head) {
stack<int> st;
ListNode *fast = head, *slow = head;
bool isodd = false;
if(!head || !head->next){ return true; }
while(fast && fast->next)
{
st.push(slow->val);
fast = fast->next->next;
slow = slow->next;
if(!fast){ isodd = true; }
}
if(!isodd){ slow = slow->next; }
while(slow)
{
if(st.top() != slow->val){ return false; }
st.pop();
slow = slow->next;
}
return true;
}
快慢指针+链表反转
要满足时间复杂度o(n),空间复杂度o(1),利用快慢指针找到链表中点位置,然后对后一半链表反转操作,再跟前一半链表比对。
bool isPalindrome(ListNode* head) {
ListNode *fast = head, *slow = head;
if(!head || !head->next){ return true; }
// find the center
while(fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
slow = slow->next;
// reverse the link
ListNode* newhead = NULL;
while(slow)
{
ListNode* t = slow->next;
slow->next = newhead;
newhead = slow;
slow = t;
}
// compare
while(newhead)
{
if(newhead->val != head->val){ return false; }
head = head->next;
newhead = newhead->next;
}
return true;
}
};