每天一道leetcode234-迴文連結串列

公眾號_程式設計師喬戈裡發表於2018-11-06

考試結束,班級平均分只拿到了年級第二,班主任於是問道:大家都知道世界第一高峰珠穆朗瑪峰,有人知道世界第二高峰是什麼嗎?正當班主任要繼續發話,只聽到角落默默想起來一個聲音:”喬戈裡峰”

前言

2018.11.6號打卡

明天的題目:leetcode-cn.com/problems/re… 以後明天的題目提取公佈一下哈,因為有些朋友想提前做一下~

題目

leetcode234-迴文連結串列 中文連結: leetcode-cn.com/problems/pa… 英文連結串列: leetcode.com/problems/pa… 難度:easy 分類:連結串列

題目詳述

請判斷一個連結串列是否為迴文連結串列。

示例 1:

輸入: 1->2 輸出: false 示例 2:

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

題目詳解

距離AC只差一個測試用例的錯誤思路

  • 之前應該有看過關於迴文連結串列的一種解法,就是對於連結串列的每個元素依次乘以1,2,3,4...求得一個和sum1;
  • 然後就是把這個連結串列反轉,反轉連結串列正好昨天做過哈,直接把程式碼拿來用,得到反轉後的連結串列;
  • 然後對於這個反轉後的連結串列,依次遍歷然後對於每個元素依次乘以1,2,3,4...求得一個和sum2;
  • 然後比較這個兩個sum值,如果相等,那麼就是迴文連結串列

程式碼

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        int sum1 = 0;
        if(head == null || head.next == null)
            return true;
        int count = 1;
        ListNode temp = head;
        while(temp != null)
        {
            sum1 += count * temp.val;
            count += 1;
            temp = temp.next;
        }
        int sum2 = 0;
        count = 1;
        head = reverseList(head);
        temp = head;
        while(temp != null)
        {
            sum2 += count * temp.val;
            count += 1;
            temp = temp.next;
        }
        if(sum1 == sum2)
            return true;
        return false;
    }
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null)
            return head;
        ListNode pre = head;
        ListNode pNode = head.next;
        ListNode next = head;
        //首先處理前兩個節點;
        pre.next = null;
        while(pNode != null)
        {
            next = pNode.next;
            pNode.next = pre;
            pre = pNode;
            pNode = next;
        }
        return pre;
    }
}
複製程式碼

結果,差一個用例沒過,說明這種方法還是有點問題~~~~

每天一道leetcode234-迴文連結串列

正確的思路

  • 由於題目說了時間複雜度是O(n),空間複雜度是O(1),所以不能使用新的空間;
  • 思路還是反轉連結串列,不過不是反轉整個連結串列,反轉的是後半部分的連結串列;
  • 後半部分的連結串列反轉完畢,然後一個從頭開始遍歷,一個從尾巴開始遍歷,依次比較節點的值是不是一樣,一樣就繼續往下,不一樣直接就返回false.

程式碼

/**
 * 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;
        int length = 0;
        ListNode temp = head;
        while(temp != null)
        {
            length++;
            temp = temp.next;
        }
        int halfLength = length / 2;
        temp = head;
        for(int i=0;i<halfLength;i++)
            temp = temp.next;
        ListNode pre = temp;
        ListNode pNode = temp.next;
        ListNode next = pNode;
        while(pNode != null)
        {
            next = pNode.next;
            pNode.next = pre;
            pre = pNode;
            pNode = next;
        }
        for(int i=0;i<halfLength;i++)
        {
            if(head.val != pre.val)
                return false;
            head = head.next;
            pre = pre.next;
        }
        return true;
    }
}
複製程式碼

程式碼講解

  • 15到20行,遍歷連結串列,求連結串列長度的一半的值
  • 22-23行,找到連結串列的中間節點
  • 24-33行反轉連結串列
  • 34-40行一個從頭,一個從尾巴,依次比較值是否相等,不相等就返回false
  • 最後就是返回true

結束語

2018.11.6號 打卡

作者喬戈裡親歷2019秋招,哈工大計算機本碩,百度准入職java工程師,歡迎大家關注我的微信公眾號:程式設計師喬戈裡。

相關文章