Leetcode_#234_回文链表

原题:#234_回文链表

  • 解法一:利用数组
    • 使用遍历把节点的值放置在新开辟的数组中。
    • 使用头尾指针,分别向中间靠近,过程中比较两个指针所指的值是否相等(注意是比较数组指针所指的值,而不是数组指针)
public boolean isPalindrome(ListNode head) {
        List<Integer> vals = new ArrayList<>();

        // Convert LinkedList into ArrayList.
        ListNode currentNode = head;
        while (currentNode != null) {
            vals.add(currentNode.val);
            currentNode = currentNode.next;
        }

        // Use two-pointer technique to check for palindrome.
        int front = 0;
        int back = vals.size() - 1;
        while (front < back) {
            // Note that we must use ! .equals instead of !=
            // because we are comparing Integer, not int.
            if (!vals.get(front).equals(vals.get(back))) {
                return false;
            }
            front++;
            back--;
        }
        return true;
    }
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

  • 解法二:快慢指针+翻转链表
    • 步骤
      • 找到第一部分的尾节点
      • 翻转后半部分节点
      • 判断是否为回文
      • 恢复链表
      • 返回结果
    • 快慢指针同时出发,快指针比慢指针快一倍,当快指针到达链表尾部时,慢指针到达链表中部
    • 若链表节点数为奇数,则中点视为前半段的节点
class Solution {

    public boolean isPalindrome(ListNode head) {

        if (head == null) return true;

        ListNode firstHalfEnd = endOfFirstHalf(head);	//找到第一部分的尾结点
        ListNode secondHalfStart = reverseList(firstHalfEnd.next); //翻转第二部分链表
		
        //判断是否为回文链表
        ListNode p1 = head;
        ListNode p2 = secondHalfStart;
        boolean result = true;
        while (result && p2 != null) {
            if (p1.val != p2.val) result = false;
            p1 = p1.next;
            p2 = p2.next;
        }        

        // 恢复原链表的结构
        firstHalfEnd.next = reverseList(secondHalfStart);
        return result;
    }

    // 翻转链表
    private ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode nextTemp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }
	
    //找到第一部分的尾节点
    private ListNode endOfFirstHalf(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值