labuladong算法公众号学习笔记
labuladong算法公众号学习笔记
labuladong算法公众号学习笔记
*寻找回文串的核心思想是从中心向两端扩展:*
string palindrome(string& s, int l, int r){
while(l >= 0 && r<s.size() && s[l] == s[r]){
//向两边展开
l--;r++;
}
//返回以s[l]和s[r]为中心的最长回文串
return s.substr(l+1, r-1-l);
}
上述函数传入l和r,就是为了处理回文串长度可能是奇数或者偶数的情况。
判断回文串:
双指针从两端向中间逼近即可。
bool isPalindrome(string s){
int left = 0, right = s.length - 1;
while(left < rihgt){
if(s[left] != s[right])
return false;
left++;right--;
}
return true;
}
回文串是对称的,所以正读和倒读是一样的。
判断回文单链表
一种方法是用反转链表的方法,将原链表反转然后对比。
另一种方法是,借助二叉树后序遍历的思路,不需要显示反转原始链表也可以倒序遍历链表。
链表也有前序遍历和后序遍历:
void traverse(ListNode head){
//前序遍历代码
traverse(head.next);
//后序遍历代码
}
如果想正序打印链表中的val值,可以在前序遍历位置写代码;如果想倒序遍历链表,可以在后序遍历位置操作。
//左指针
ListNode left;
boolean isPalindrome(ListNode head){
left = head;
return traverse(head);
}
boolean traverse(ListNode right){
if(right == null) return true;
boolean res = traverse(right.next);
//后序遍历代码
res = res && (right.val == left.val);
left = left.next;
return res;
}
我还是没怎么明白orz
优化空间复杂度
1、 先用 双指针技巧 中的快慢指针来找到链表的中点:
ListNode slow,fast;
slow = fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
//slow指针现在在链表中点
2、如果fast指针没有指向null,说明链表长度为奇数,slow还要再前进一步:
if(fast != null){
slow = slow.next;
}
3、从slow开始反转后面的链表,现在就可以开始比较回文串了:
ListNode left = head;
ListNode right = reverse(right);
while(right != null){
if(left.val != right.val){
return false;
}
left = left.next;
right = right.next;
}
return true;
把上述三段合起来:
ListNode reverse(ListNode head){
ListNode pre = null, cur = head;
while(cur != null){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}