首页 > 其他分享 >[LeetCode Hot 100] LeetCode234. 回文链表

[LeetCode Hot 100] LeetCode234. 回文链表

时间:2023-12-05 12:13:31浏览次数:37  
标签:head LeetCode234 ListNode val next 链表 Hot 指针

题目描述

思路1:将值复制到数组中然后使用双指针

  1. 计算链表的长度
  2. 创建等长的数组
  3. 将链表中的数依次放入数组中
  4. 使用左右指针判断链表是否是回文链表

时间复杂度:O(n)
空间复杂度:O(n)

思路2:快慢指针+反转链表

  • 用快慢指针,快指针走两步,慢指针走一步,快指针遇到终止位置时,慢指针就在链表中间位置
  • 同时用pre记录慢指针指向节点的前一个节点,用来分割链表
  • 将链表分为前后均等两部分,如果链表长度是奇数,那么后半部分多一个节点
  • 将后半部分翻转,得到cur2,前部分为cur1
  • 按照cur1的长度,依次比较cur1和cur2的节点数值

方法一:对于思路1

/**
 * 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) {
        ListNode p = head;
        int length = 0;

        List<Integer> list = new ArrayList<>();
        int index = 0;

        // 计算链表的长度,并且将链表的值依次存入链表中
        while (p != null) {
            list.add(p.val);
            p = p.next;
            index ++;
        }

        // 使用左右指针,判断链表是否是回文链表
        int left = 0, right = list.size() - 1;
        for (;left <= right; left ++, right--) {
            if (list.get(left) != list.get(right)) {
                return false;
            }
        }
        return true;
    }
}

方法二:对应思路2

/**
 * 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) {
        // 1. 链表如果为空或者仅有一个节点,返回true
        if (head == null && head.next == null) return true;
        // 2. 定义快慢指针
        ListNode slow = head;
        ListNode fast = head;
        ListNode pre = head;
        while (fast != null && fast.next != null) {
            // pre指针记录slow的前一个节点
            pre = slow;
            // fast指针一次走两步
            fast = fast.next.next;
            // slow指针一次走一步
            slow = slow.next;
        }
        // 分隔两个链表
        pre.next = null;
        // 前半部分
        ListNode cur1 = head;
        ListNode cur2 = reverseList(slow);

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

    /**
        反转链表的代码
     */
    private ListNode reverseList(ListNode head) {
        ListNode curNode = head;
        ListNode preNode = null;
        ListNode nextNode;
        while (curNode != null) {
            nextNode = curNode.next;
            curNode.next =  preNode;
            preNode = curNode;
            curNode = nextNode;
        }
        return preNode;
    }
}

标签:head,LeetCode234,ListNode,val,next,链表,Hot,指针
From: https://www.cnblogs.com/keyongkang/p/17876927.html

相关文章

  • [LeetCode Hot 100] LeetCode206. 反转链表
    题目描述思路:双指针算法方法一:/***Definitionforsingly-linkedlist.*publicclassListNode{*intval;*ListNodenext;*ListNode(){}*ListNode(intval){this.val=val;}*ListNode(intval,ListNodenext){this.val=v......
  • [LeetCode Hot 100] LeetCode49. 字母异位词
    题目描述思路:哈希表对字符串排序,如果是异位词,排序后就变成一样的了。方法一:classSolution{publicList<List<String>>groupAnagrams(String[]strs){Map<String,List<String>>map=newHashMap<>();for(inti=0;i<strs.length;i......
  • [LeetCode Hot 100] LeetCode141. 环形链表
    题目描述思路:快慢指针slow指针:每次移动一个节点fast指针:每次移动两个节点如果链表中存在环,fast指针最终会在某一时刻追上slow指针,这是由于移动速度快的fast指针会在某个时刻绕圈并追上速度慢的slow指针条件fast!=null&&fast.next!=null保证了在每一步迭代中,fast和......
  • [LeetCode Hot 100] LeetCode3. 无重复字符的最长子串
    题目描述思路:滑动窗口定义需要维护的变量//1.定义需要维护的变量intmax_len=0;Map<Character,Integer>hashmap=newHashMap<>();窗口不满足条件,窗口收缩。窗口不是固定大小所以用while//4.窗口不满足条件:窗口收缩//满足这个条件说明有重复元素//这......
  • [LeetCode Hot 100] LeetCode438. 找到字符串中所有字母异位词
    题目描述思路:滑动窗口模板需要维护的变量://1.用于存放结果List<Integer>res=newArrayList<>();//2.定义需要维护的变量:根据题意可知是一个哈希表Map<Character,Integer>map=newHashMap<>();Map<Character,Integer>hashmap_p=newHashMap<>();for(c......
  • 链表算法笔记
    ​ 类型:单链表、双链表、循环链表操作:删除节点、添加节点        在删除节点时,C++里最好是再手动释放所删除的节点,释放内存,但是如Java、Python等语言,它们有自己的内存回收机制,就不需要手动释放了。使用虚拟头节点的原因使第一个节点和其他节点的增加和删除操作统一,......
  • 内核链表
    内核链表在很多嵌入式的代码中都有用到,因为这个链表很好用,并且代码的统一性会增强代码的可读性,因此这里简单记录一下内核链表的使用,首先是库文件,这里也就是从内核中获取的,下面的代码做了一点注释。#ifndef_LINUX_LIST_H#define_LINUX_LIST_H//include/linux/types.hstruct......
  • [LeetCode Hot 100] LeetCode1. 两数之和
    题目描述思路:如果哈希表存在target-nums[i],则返回索引下标i和对应的key值(可以按任意顺序返回答案)如果哈希表中不存在target-nums[i],则存入nums[i]和对应的索引值方法一:哈希表classSolution{publicint[]twoSum(int[]nums,inttarget){//1.存放......
  • 链表算法总结
    知识概览链表包括单链表和双链表,这里讨论算法题中的链表。为了考虑算法题中对于时间效率的要求,链表通常是用数组模拟成静态链表的形式,速度快。单链表可以用来写邻接表(包括n个链表),邻接表可以存储树和图,最短路问题、最小生成树问题、最大流问题都可以用邻接表来存储。双链表用来......
  • 链表为什么适合归并排序而不是快速排序?
    链表适合归并排序而不是快速排序的原因主要有以下几点:内存访问模式:快速排序的效率主要来源于引用的局部性,计算机硬件在这里得到了优化,因此访问彼此相邻的内存位置往往比访问分散在内存中的内存位置更快。然而,链表单元格经常分散在内存中,所以访问相邻的链表单元格没有局部性......