• 【leetcode】234. 回文链表


    题目:234. 回文链表

    思路:转换成数组,用双指针判断

    代码:

    /**
     * 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 boolean isPalindrome(ListNode head) {
            List<Integer> vals = new ArrayList<Integer>();
            ListNode p = head;
            while(p!=null){
                vals.add(p.val);
                p = p.next;
            }
    
            int L = 0;
            int R = vals.size()-1;
            while(L<R){
                if(!vals.get(L).equals(vals.get(R))) return false;
                L++;
                R--;
            }
    
            return true;
    
            
    
        }
    
        
    }

    思路2:

    递归:链表兼具递归结构,树结构不过是链表的衍生。那么,链表其实也可以有前序遍历和后序遍历:

    如果我想正序打印链表中的 val 值,可以在前序遍历位置写代码;反之,如果想倒序遍历链表,就可以在后序遍历位置操作:

    如下:

    /* 倒序打印单链表中的元素值 */
    void traverse(ListNode head) {
        if (head == null) return;
        traverse(head.next);
        // 后序遍历代码
        print(head.val);
    }

    说到这了,其实可以稍作修改,模仿双指针实现回文判断的功能:

    /**
     * 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 {
        ListNode left;
        public boolean isPalindrome(ListNode head) {
            left = head;
            return travse(head);
        }
    
        boolean travse(ListNode right){
            if(right == null) return true;
            boolean res = travse(right.next);
            res = res && (right.val == left.val);
            left = left.next;
            return res;
        }
    
        
    }

    更优解:

    1、先通过 双指针技巧 中的快慢指针来找到链表的中点:

    2、如果fast指针没有指向null,说明链表长度为奇数,slow还要再前进一步:

    3、从slow开始反转后面的链表,现在就可以开始比较回文串了:

    代码

    boolean isPalindrome(ListNode head) {
        ListNode slow, fast;
        slow = fast = 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 = reverse(slow);
        while (right != null) {
            if (left.val != right.val)
                return false;
            left = left.next;
            right = right.next;
        }
        
        return true;
    }
    
    ListNode reverse(ListNode head) {
        ListNode pre = null, cur = head;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
  • 相关阅读:
    组合数
    POJ2774 Long Long Message
    后缀排序【后缀数组入门题】
    luogu P3205 [HNOI2010]合唱队 区间dp
    luogu P3119 [USACO15JAN]Grass Cownoisseur G 有向图强连通分量+分层最短路
    luogu P3469 [POI2008]BLO-Blockade 割点
    luogu P2569 [SCOI2010]股票交易 单调优化dp
    luogu P2939 [USACO09FEB]Revamping Trails G 分层最短路
    luogu P3957 跳房子 二分+斜率优化dp
    luogu P1772 [ZJOI2006]物流运输 spfa最短路+dp
  • 原文地址:https://www.cnblogs.com/xiangshigang/p/16215776.html
Copyright © 2020-2023  润新知