234. 回文链表_详细解答(java)

文章目录

  • 234. 回文链表
  • 思路与代码(java)
    • 方法一,双循环,(比较容易懂)
    • 方法二,快慢指针,(有点难度)
    • 方法三,递归,(有点难度)
  • 参考资料

234. 回文链表

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

思路与代码(java)

方法一,双循环,(比较容易懂)

简单来说就是把链表的元素都装到数组,利用数组可以随机访问的特性,双指针,一个在头加加,一个在尾减减,不相同直接 retrun false

1 2 3 2 1
头指针 —> <— 尾指针
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
		if(head==null || head.next==null) {
			return true;
		}
		java.util.ArrayList<Integer> arr = new java.util.ArrayList<Integer>();
		//申请一个容器,然后把元素都放到数组中
		while(head!=null) {
			arr.add(head.val);
			head = head.next;
		}
		int i = 0;
		int j = arr.size()-1;
		//用i和j两个指针,一个往后,一个往前,不断迭代
		//如果i的值不等于j说明不是回文,反之是回文
		while(i<j) {
			if(arr.get(i).compareTo(arr.get(j))!=0) {
				return false;
			}
			++i;
			--j;
		}
		return true;        
    }
}

执行用时 :4 ms, 在所有 Java 提交中击败了23.46%的用户
内存消耗 :40.7 MB, 在所有 Java 提交中击败了97.70%的用户

方法二,快慢指针,(有点难度)

使用快慢两个指针找到链表中点,慢指针每次前进一步,快指针每次前进两步。在慢指针前进的过程中,同时修改其 next 指针,使得链表前半部分反序。最后比较中点两侧的链表是否相等。

class Solution {
  public boolean isPalindrome(ListNode head) {
    if (head == null || head.next == null) {
      return true;
    }

    ListNode prev = null;
    ListNode slow = head;
    ListNode fast = head;

    while (fast != null && fast.next != null) {
      fast = fast.next.next;
      ListNode next = slow.next;
      slow.next = prev;
      prev = slow;
      slow = next;
    }

    if (fast != null) {
      slow = slow.next;
    }

    while (slow != null) {
      if (slow.val != prev.val) {
        return false;
      }
      slow = slow.next;
      prev = prev.next;
    }

    return true;
  }
}

执行用时 :1 ms, 在所有 Java 提交中击败了99.53%的用户
内存消耗 :41.5 MB, 在所有 Java 提交中击败了97.32%的用户

方法三,递归,(有点难度)

class Solution {

    private ListNode frontPointer;

    private boolean recursivelyCheck(ListNode currentNode) {
        if (currentNode != null) {
            if (!recursivelyCheck(currentNode.next)) return false;
            if (currentNode.val != frontPointer.val) return false;
            frontPointer = frontPointer.next;
        }
        return true;
    }

    public boolean isPalindrome(ListNode head) {
        frontPointer = head;
        return recursivelyCheck(head);
    }
}

来自

参考资料

回文链表-leetcode
回文链表-刷题

你可能感兴趣的:(零基础学数据结构,acm)