public static String palindrome(String s, int left, int right){
while(left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return s.substring(left + 1, right);
}
//主函数
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int left, right;
if(s.length() % 2 == 0) {
right = s.length() / 2;
left = right - 1;
}else{
left = right = s.length() / 2;
}
System.out.println("left" + left + " right:" + right);
System.out.println(palindrome(s,left,right));
}
public static boolean isPalindrome(String s){
int left = 0;
int right = s.length() - 1;
while(left < right){
if(s.charAt(left) == s.charAt(right)){
left++;
right--;
}
else
return false;
}
return true;
}
class Solution {
public ListNode left = null;
public boolean traverse(ListNode right){
if(right == null)
return true;
boolean res = traverse(right.next) && (left.val == right.val);
left = left.next;
return res;
}
public boolean isPalindrome(ListNode head) {
left = head;
return traverse(left);
}
}
太牛了,东哥这个思想:树是由链表衍生出来的,所以链表也可以前序、后序遍历。
树的遍历:
void traverse(TreeNode root) {
// 前序遍历代码
traverse(root.left);
// 中序遍历代码
traverse(root.right);
// 后序遍历代码
}
void traverse(ListNode head) {
// 前序遍历代码
traverse(head.next);
// 后序遍历代码
}
//正序输出
public static void traverse(ListNode head) {
if(head == null)
return;
// 前序遍历代码
System.out.println(head.val);
traverse(head.next);
// 后序遍历代码
}
//逆序输出
public static void traverse(ListNode head) {
if(head == null)
return;
// 前序遍历代码
traverse(head.next);
// 后序遍历代码
System.out.println(head.val);
}
public static ListNode reverseList_iteration(ListNode head){
ListNode pre, cur, nxt;
pre = null; cur = head; nxt = head;
while(cur != null){
//标记后继指针
nxt = cur.next;
//反转
cur.next = pre;
//更新 cur、pre指针
pre = cur;
cur = nxt;
}
return pre;
}
public static Boolean ispalindrome(ListNode head){
if(head == null)
return true;
ListNode fast, slow;
fast = slow = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
if(fast! = null)
slow = slow.next;
ListNode left = head;
ListNode right = reverseList_iteration(slow.next);
while(right != null){
if(right.val == left.val){
left = left.next;
right = right.next;
}
else return false;
}
slow.next = reverseList_iteration(right);
return true;
}
为什么有这一行呢?( if(fast! = null) slow = slow.next;),看下图:很显然,当链表数目为奇数的时候,slow指针并没有指到对应的位置,只有向后再走一步,链表反转才有意义。注意这里的条件不能写成fast.next ==null,这样会报空指针异常,因为出循环的也有可能是fast == null。
这个程序执行完之后,虽然运行成功,但是链表结构发生了改变,如下图:
如果想要保证链表结构不变 ,救灾输出的时候把链表还原出来,也就是这里东哥所说的q为头节点的链表反转之后,用p指针将它们连起来,如下图:
如果引入p,q指针显然又要申请额外的内存空间,不划算,我们在原来程序的基础上做一个改进,看下面的代码:
public boolean isPalindrome(ListNode head) {
ListNode fast, slow;
fast = slow = head;
//这样就保证不管是奇数还是偶数的链表,slow指针都差一个才到位置,也就是p指针指的地方
while(fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode left = head;
//而right指针正好就是q指针指的地方,用fast1存储,这样就完美的解决了不额外申请空间的问题
ListNode right = reverseList_iteration(slow.next);
ListNode fast1 = right;
while(right != null){
if(right.val == left.val){
left = left.next;
right = right.next;
}
else return false;
}
slow.next = reverseList_iteration(fast1);
return true;
当然想让它看起来再舒服一点,将代码做一改进:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode endFirstHalf(ListNode head){
ListNode fast, slow;
fast = slow = head;
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
public ListNode reverse(ListNode head){
ListNode pre,cur,nxt;
pre = null;cur = head; nxt = head;
while(cur != null){
nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
public boolean isPalindrome(ListNode head) {
if(head == null)
return true;
ListNode left = head;
//用来储存节点,方便后续还原链表,这里的firstPosition就是上面所说的slow
ListNode firstPosition = endFirstHalf(head);
ListNode secondPosition = reverse(firstPosition.next);
ListNode right = secondPosition;
while(right != null){
if(left.val != right.val)
return false;
left = left.next;
right = right.next;
}
firstPosition.next = reverse(secondPosition);
return true;
}
}
参考:
https://labuladong.github.io/algo/di-yi-zhan-da78c/shou-ba-sh-8f30d/ru-he-pan–f9d3c/
https://leetcode.cn/problems/palindrome-linked-list/solution/hui-wen-lian-biao-by-leetcode-solution/