zoukankan      html  css  js  c++  java
  • leetcode题目234.回文链表(快慢指针+辅助空间-简单)

    题目描述:

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

    示例 1:
    
    输入: 1->2
    输出: false
    示例 2:
    
    输入: 1->2->2->1
    输出: true
    进阶:
    你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

    思路分析:

    思路一:借助辅助栈和辅助队列,链表节点依次入队列和入栈,依次出栈和出队,判断是否相等即可

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
          public static boolean isPalindrome(ListNode head) {
    
            //借助一个栈和一个队列去判断
            Deque<ListNode> deque = new LinkedList<>();
            Stack<ListNode> helper = new Stack<>();
            int count = 0;
            while (head != null) {
                deque.addLast(head);
                helper.push(head);
                head = head.next;
                count++;
            }
            for (int i = 0; i < count; i++) {
                if (deque.poll().val != helper.pop().val) {
                    return false;
                }
            }
    
            return true;
        }
    }

    时间复杂度:O(n)

    空间复杂度:O(2n)->O(n)

    思路二:快慢指针

    思想很简单,用2个指针,一个low,一个fast,fast是low的2倍,所以可以达到2分链表的效果,在移动指针时同时对前半部分链表进行反转。最后直接比较被分开的2个链表。因为不能改变当前slow的next,不然就无法跳到下一个元素,所以这里用pre和prepre实现指针的反转

    代码实现:

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
           //快慢指针:边遍历边翻转前半段
        public static boolean isPalindrome(ListNode head) {
    
            if (head == null || head.next == null) {
                return true;
            }
            ListNode slow = head;
            ListNode fast = head.next;
            ListNode preNode = null;
            ListNode pre2Node = null;
            while (fast != null && fast.next != null) {
    
                preNode = slow;
                //此处因为不能丢失slow.next,所以使用preNode和pre2Node实现链表的翻转
                slow = slow.next;
                fast = fast.next.next;
                preNode.next = pre2Node;
                pre2Node = preNode;
            }
            //链表被分成两个部分,qNode表示后链表的头
            ListNode qNode = slow.next;
            //注意,因为之前没有指定slow.next指向哪个节点,此处要做指定(之前为了持续遍历,slow.next一直指向原链表的下一个节点)
            slow.next = preNode;
            //考虑奇偶:如果链表节点个数为偶数,则前链表的表头为slow,否则为slow.next
            ListNode pNode = fast == null ? slow.next : slow;
            while (qNode != null && pNode != null) {
                if (qNode.val != pNode.val) {
                    return false;
                }
                qNode = qNode.next;
                pNode = pNode.next;
            }
            return true;
        }
    }

    时间复杂度:O(n)

    空间复杂度:O(1)

  • 相关阅读:
    实验5 函数
    实验4 在分支循环结构中调用自定义函数
    Play 内置标签
    POI 正常输出WORD 文档
    用户WORD模板写文件
    Spring 注解过滤
    Spring 循环依赖
    Spring 表单标签
    WebService 客户端生成服务端代码
    Jquery 常用函数
  • 原文地址:https://www.cnblogs.com/ysw-go/p/11903763.html
Copyright © 2011-2022 走看看