leetcode:回文链表(java,考察点:单向链表的遍历)

题目

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

示例 1:

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

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

思路

  1. 创建一个数据或者栈来存储链表中的所有值,通过首尾的匹配来判断是否回文
  2. 将链表一分为2,将其中一个反转,遍历是否相等

java

创建栈、数组、不满足空间复杂度为O(1)

// 数组
class Solution {
    public boolean isPalindrome(ListNode head) {
        
        List<Integer> list = new ArrayList();
        while(head != null)
        {
            list.add(head.val);
            head = head.next;
        }
        for (int i = 0;i < list.size();i ++)
        {
            if (!list.get(i).equals(list.get(list.size() - i - 1)))
            {
                return false;
            }
        }
        return true;
    }
}

// 栈
class Solution {
    public boolean isPalindrome(ListNode head) {
        
        ListNode p = head;
        Stack<Integer> s = new Stack();
        while(p!=null){
            s.push(p.val);
            p=p.next;
        }
        while(!s.empty()){
            if(head.val!=s.pop()){
                return false;
            }
            head=head.next;
        }
        return true;    
    }
}
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        // 先找到中间节点,然后反转前一部分,之后两段链表进行比较
        // 1.找到中间节点,一个快,一个慢
        ListNode fast = head;
        ListNode slow = head;
        if (fast == null || fast.next == null) {// 如果没有元素或只有一个元素,就直接返回true
            return true;
        }

        while (fast.next != null && fast.next.next != null) {// 找到第(n+1)/2的指针位置,n为元素的个数,比如有3个元素,那么
            fast = fast.next.next;                       // slow就在2这个位置,如果为4,还是在2这个位置,
            slow = slow.next;                            // 因为回文是121,1221,需要考虑奇数位还是偶数位
        }
        
        int flag = 0;// 标志位,判断链表是奇数位还是偶数位,为1说明是奇数位
        if (fast.next == null) {
            flag = 1;
        }

        ListNode head2 = slow.next;// 第二段链表的开头指针
        // 反转链表
        ListNode pre = null;
        ListNode now = head;
        ListNode next = head;
        while (next != head2) {
            next = now.next;
            now.next = pre;

            pre = now;
            now = next;
        }

        if (flag == 1) {// 如果是奇数位像121,中间的2不参与判断,就像原来是1->2->1,反转之后一段位2->1,,另一段是1,
            pre = pre.next;
        }

        while (head2 != null) {
            if (head2.val != pre.val) {
                return false;
            }
            
            head2 = head2.next;
            pre = pre.next;
        }
        return true;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39313597/article/details/89084256