LeetCode-探索-初级算法-链表-5. 回文链表(个人做题记录,不是习题讲解)

LeetCode-探索-初级算法-链表-5. 回文链表(个人做题记录,不是习题讲解)

LeetCode探索-初级算法:https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/

  1. 回文链表
  • 语言:java

  • 思路:就是用List把回文判断变成数组形式。中间遇到了一个Java的基础知识问题,就是Integer默认常量池-128~127,也就是这之间的Integer是指向同一个地址,如果超出范围,可能出现a!=b的情况,需要转换成int比较(或者用equals比较值,==比较地址)。

  • 代码(5ms,23.43%,写得太烂):

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public boolean isPalindrome(ListNode head) {
            List<Integer> arr = new ArrayList<>();
            while(head!=null){
                arr.add(head.val);
                head = head.next;
            }
            int len = arr.size();
            for(int i = 0, j = len-1; i < j; ++i, --j){
                if((int)arr.get(i)!=(int)arr.get(j))
                    return false;
            }
            return true;
        }
    }
    
  • 参考代码(1ms):思路就是先找到中间节点,然后反转中间到最后的链表,然后分别从头和尾判断值相等。

    class Solution {
        public boolean isPalindrome(ListNode head) {
            if(head == null || head.next == null){
                return true;
            }
            ListNode cur = middle(head);
            ListNode prev = null;
            while(cur != null){   //反转链表
              ListNode next = cur.next;
              cur.next = prev;
              prev = cur;
              cur = next;
            }
            ListNode tem = head;
            while(prev != null){  //比较
                if(prev.val != tem.val){
                    return false;
                }
                prev = prev.next;
                tem = tem.next;
            }
            return true;
        }
        public int size(ListNode head){
            ListNode cur;
            int len = 0;
            for(cur = head; cur != null; cur = cur.next){
                len++;
            }
            return len;
        }
        public ListNode middle(ListNode head){
            int i = 0;
            ListNode cur = head;
            int len = size(head)/2;
            while(i < len){   //找中间值
                cur = cur.next;
                i++;
            }
            return cur;
        }
    }
    
  • 参考后重写(2ms):慢1ms估计是什么地方可以优化,但是整体思路和写法因该和参考代码是一样的。

    class Solution {
       public boolean isPalindrome(ListNode head) {
            ListNode start = head;
            ListNode middle = middle(head);//求出中间节点
            ListNode end = reverseList(middle);//把中间往后的节点反转
            while(end!=null){
                if(start.val!=end.val)
                    return false;
                start = start.next;
                end = end.next;
            }
            return true;
        }
        /* 求中间节点 */
        public ListNode middle(ListNode head){
            int pos = size(head) / 2;
            ListNode start = head;
            while(pos-- > 0){
                start = start.next;
            }
            return start;
        }
        /* 求链表长度 */
        public int size(ListNode head){
            ListNode start = head;
            int len = 0;
            while(start!=null){
                ++len;
                start = start.next;
            }
            return len;
        }
        /* 反转链表 */
        public ListNode reverseList(ListNode head){
            ListNode next = head,pre = null,cur = null;
            while(next!=null){
                pre = cur;
                cur = next;
                next = next.next;
                cur.next = pre;
            }
            return cur;
        }
    }
    

你可能感兴趣的:(LeetCode,非讲解,原创)