代码随想录:链表

news2024/12/22 21:03:52

文章目录

  • 代码随想录---链表
    • 链表基础(创建以及增删查改)
      • 设计链表
    • 链表的反转
      • [206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)
        • 递归法
        • 迭代法
    • 删除链表倒数第N个结点
      • [19. 删除链表的倒数第 N 个结点](https://leetcode.cn/problems/remove-nth-node-from-end-of-list/)
    • 链表有环判断环入口问题
      • [142. 环形链表 II](https://leetcode.cn/problems/linked-list-cycle-ii/)
        • 快慢指针法
        • 哈希表法

代码随想录—链表

嗨嗨,越是到了期末周,越是想开摆。复习什么的,60分万岁吧。有些东西真不感兴趣了。


这次是来到了链表篇(毕竟链表和数组在数据结构中很是重要)

这里我基本都是使用的迭代法(递归法得慢慢修炼修炼再考虑了)

(从大一c语言学习的时候,就觉得大多数情况下都能约定好使用的是虚拟头结点就好了)

所以推荐使用链表时都使用一个虚拟头结点(力扣人好像喜欢叫哑结点)

偶尔的话可以使用哨兵结点,用于减少判断条件或者越界

先大概概括一下基本题型吧

  • 链表的建立以及增删查改
    • 虚拟头结点的使用,temp临时指针等
    • 边界条件判断(什么时候使用current !=null 什么时候使用current.Next !=null)
    • 拓展: 双向链表,循环链表(记得试试约瑟夫环这个经典问题)
  • 反转链表
    • 原地反转(注意使用指针保存下一个结点)
    • 新建头结点然后使用头插
  • 删除链表倒数第N个结点
    • 直接暴力,第一次先算链表长度,第二次遍历删除该结点
    • 使用前后指针,先让快指针走N步,然后慢指针开始出发。
  • 判断是否有环
    • 让你判断是否有环
      • 快慢指针
      • 哈希表
    • 寻找环的入口
      • 快慢指针
      • 哈希表

链表基础(创建以及增删查改)

力扣相关题目(也可以看看数据结构相关书籍,那边基础功能更多更全)

设计链表

class MyLinkedList {
    private ListNode head;
    int size;
    private static class ListNode{
        int val;
        ListNode next;
        ListNode(int val){
            this.val =val;
            this.next = null;
        }
        ListNode(){}
    }
    public MyLinkedList() {
        size=0;
        head =new ListNode(-1);
    }

    public int get(int index) {
        if(index>=size|| index<0){
            return -1;
        }
        ListNode current=head;
        int i=0;

        while(i<=index){
            current = current.next;
            i++;
        }
        return current.val;
    }

    public void addAtHead(int val) {
       addAtIndex(0,val);

    }

    public void addAtTail(int val) {
       addAtIndex(size,val);
    }

    public void addAtIndex(int index, int val) {
        if(index>size){
            return;
        }
         index = Math.max(0, index);
        int i=0;
        size++;
        ListNode newNode=new ListNode(val);
        ListNode current=head;
        while(i<index){
           i++;
            current=current.next;
       }
       newNode.next=current.next;
       current.next=newNode;
    }

    public void deleteAtIndex(int index) {
        if(index>=size|| index<0){
            return;
        }
        size--;
        ListNode current= head;
        int i=0;
        while(i<index){
            i++;
            current=current.next;
        }
        current.next=current.next.next;

    }
}
type ListNode struct {
	Val  int
	Next *ListNode
}

type MyLinkedList struct {
	head *ListNode
	size int
}

func Constructor() MyLinkedList {
	return MyLinkedList{&ListNode{}, 0}
}

func (l *MyLinkedList) Get(index int) int {
	if index < 0 || index >= l.size{
		return -1
	}
	current := l.head
	for i:=0;i<=index;i++{
		current = current.Next
	}
	return current.Val
}
func (l*MyLinkedList)AddAtHead(val int){
	l.AddAtIndex(0,val)
}
func (l*MyLinkedList)AddAtTail(val int){
	l.AddAtIndex(l.size,val)
}
func (l*MyLinkedList)AddAtIndex(index, val int){
	if index > l.size{
		return 
	}
	index =max(index,0)	
	//if index < 0 {
	//	index = 0
	//}
	current :=l.head
	for i:=0;i<index;i++{
		current = current.Next
	}
	l.size++
	 toAdd := &ListNode{val, current.Next}
	//toAdd.Next=current.Next
	current.Next=toAdd
}
func (l*MyLinkedList) DeleteAtIndex(index int){
	if index >=l.size || index <0{
		return 
	}
	current :=l.head
	for i:=0;i<index;i++{
		current=current.Next
	}
	l.size--
	current.Next=current.Next.Next
}

func max(a, b int) int {
    if b > a {
        return b
    }
    return a
}

链表的反转

206. 反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

img

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

img

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]
递归法
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        ListNode last=reverseList(head.next);
        head.next.next=head;
        head.next=null;
        return last;
    }
}
迭代法
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
   ListNode p =head.next;

   head.next=null;

   ListNode q;

   while(p!=null){
       q=new ListNode();

       q.val=p.val;

       q.next=head;

       head=q;

       p=p.next;

    }
    return head;
    }
}
func reverseList(head *ListNode) *ListNode {
    if head == nil {
        return nil
    }
    var pre *ListNode
    current := head
    for current !=nil {
        temp := current.Next
        current.Next=pre
        pre=current
        current = temp
    }
    return pre

}

删除链表倒数第N个结点

19. 删除链表的倒数第 N 个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

img

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

输入:head = [1], n = 1
输出:[]

示例 3:

输入:head = [1,2], n = 1
输出:[1]
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func removeNthFromEnd(head *ListNode, n int) *ListNode {
    demmyHead := &ListNode{0,head}
    fast,slow := demmyHead,demmyHead
    f :=0
    for f < n {
        f++
        fast=fast.Next
    }
    for fast.Next!=nil {
        fast=fast.Next
        slow=slow.Next
    }
    slow.Next=slow.Next.Next
    return demmyHead.Next
}

链表有环判断环入口问题

142. 环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos-1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

img

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

img

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

img

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
快慢指针法
 type ListNode struct {
    Val int
    Next *ListNode 
 }

func detectCycle(head *ListNode) *ListNode {
    fast,slow := head ,head
    for fast != nil && fast.Next!=nil && fast.Next.Next!=nil{
        fast = fast.Next.Next
        slow = slow.Next
        if fast == slow {
            fast = head 
            for fast != slow {
                    fast = fast.Next
                    slow = slow.Next
            }
            return fast
        }
    }
    return nil
    
}

哈希表法
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode current =  head;
        Set<ListNode>hashSet =new HashSet<ListNode>();
        while(current!=null){
            if(hashSet.contains(current)){
                return current;
            }else {
                hashSet.add(current);
            }
            current=current.next;
        }
        return null;
    }
}
func detectCycle(head *ListNode) *ListNode {
    hashMap := map[*ListNode]int{}
    current := head 
    for current != nil {
        if _,ok :=hashMap[current]; ok {
            return current
        }else {
            hashMap[current]=1
        }
        current = current.Next
    }
    return nil
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1876979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3ds Max导出fbx贴图问题简单记录

1.前言 工作中发现3ds Max导出的fbx在其它软件&#xff08;Autodesk viewer&#xff0c;blender&#xff0c;navisworks&#xff0c;FBXReview等&#xff09;中丢失了部分贴图&#xff0c;但导出的fbx用3ds Max打开却正常显示。 fbx格式使用范围较广&#xff0c;很多常见的三…

基于MDEV的PCI设备虚拟化DEMO实现

利用周末时间做了一个MDEV虚拟化PCI设备的小试验&#xff0c;简单记录一下&#xff1a; DEMO架构&#xff0c;此图参考了内核文档&#xff1a;Documentation/driver-api/vfio-mediated-device.rst host kernel watchdog pci driver: #include <linux/init.h> #include …

【Java】面试必问之Java常见线上故障排查方案详解

一、问题解析 在软件开发过程中&#xff0c;排查和修复产线问题是每⼀位⼯程师都需要掌握的基本技能。但是在⽣产环境中&#xff0c; 程序代码、硬件、⽹络、协作软件等任⼀因素&#xff0c;都会引发意想不到的问题&#xff0c;所以排查产线问题⽐较困 难&#xff0c;所以问…

关于数据库的ACID几点

首先的话就是关于ACID&#xff0c;最重要的就是原子性了&#xff0c;这是基础。 原子性是指事务包含的所有操作&#xff0c;要么全部完成&#xff0c;要么全部不完成。如果不能保证原子性&#xff0c;可能会出现以下问题&#xff1a; 数据不一致&#xff1a;事务中的部分操作…

QT事件处理及实例(鼠标事件、键盘事件、事件过滤)

这篇文章通过鼠标事件、键盘事件和事件过滤的三个实例介绍事件处理的实现。 鼠标事件及实例 鼠标事件包括鼠标的移动、按下、松开、单击和双击等。 创建一个MouseEvent项目&#xff0c;通过项目介绍如何获得和处理鼠标事件。程序效果如下图所示。 界面布局代码如下&#xff…

【算法训练记录——Day36】

Day36——贪心Ⅳ 1.leetcode_452用最少数量的箭引爆气球2.leetcode_435无重叠区间3.leetcode_763划分字母区间4.leetcode_ 1.leetcode_452用最少数量的箭引爆气球 思路&#xff1a;看了眼题解&#xff0c;局部最优&#xff1a;当气球出现重叠&#xff0c;一起射&#xff0c;所用…

【工具推荐】Nuclei

文章目录 NucleiLinux安装方式Kali安装Windows安装 Nuclei Nuclei 是一款注重于可配置性、可扩展性和易用性的基于模板的快速漏洞验证工具。它使用 Go 语言开发&#xff0c;具有强大的可配置性、可扩展性&#xff0c;并且易于使用。Nuclei 的核心是利用模板&#xff08;表示为简…

多机调度问题

#include<iostream> #include<string> using namespace std; struct work {int time;int number; }; int setwork0(int m,int n,int a[],struct work w[]) {int maxtime0;for(int i1; i<m; i){cout<<i<<"号设备处理作业"<<w[i].num…

AD9026芯片开发实录5-ADRV9026 - FAQ

1. What information should I provide to help speed resolution of my issue?  Please provide as much detail as possible including all of the detail described in the table below 2. What are the key specifications of ADRV9026 chip?  The ADRV9026 is a 4…

kafka学习笔记08

Springboot项目整合spring-kafka依赖包配置 有这种方式&#xff0c;就是可以是把之前test里的配置在这写上&#xff0c;用Bean注解上。 现在来介绍第二种方式&#xff1a; 1.添加kafka依赖&#xff1a; 2.添加kafka配置方式: 编写代码发送消息&#xff1a; 测试&#xff1a; …

ROS2自定义接口Python实现机器人移动

1.创建机器人节点接口 cd chapt3_ws/ ros2 pkg create example_interfaces_rclpy --build-type ament_python --dependencies rclpy example_ros2_interfaces --destination-directory src --node-name example_interfaces_robot_02 --maintainer-name "Joe Chen" …

【STM32】在标准库中使用定时器

1.TIM简介 STM32F407系列控制器有2个高级控制定时器、10个通用定时器和2个基本定时器。通常情况下&#xff0c;先看定时器挂在哪个总线上APB1或者APB2&#xff0c;然后定时器时钟需要在此基础上乘以2。 2.标准库实现定时中断 #ifndef __BSP_TIMER_H #define __BSP_TIMER_H#if…

计算机基础知识——C基础+C指针+char类型

指针 这里讲的很细 https://blog.csdn.net/weixin_43624626/article/details/130715839 内存地址&#xff1a;内存中每个字节单位都有一个编号&#xff08;一般用十六进制表示&#xff09; 存储类型 数据类型 *指针变量名&#xff1b;int *p; //定义了一个指针变量p,指向的数…

自研Eclipse插件的生成及安装和使用

说明&#xff1a; 本处是使用个人自研的Eclipse插件为例&#xff0c;创建了一个菜单式的插件组&#xff0c;插件组下&#xff0c;有一个生成右击Jakarta EE服务端点类后&#xff0c;生成端点对应的Restful客户端。有什么问题&#xff0c;欢迎大家交流&#xff01;&#xff01;…

仓库管理系统11--物资设置

1、添加用户控件 <UserControl x:Class"West.StoreMgr.View.GoodsTypeView"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc"http://schemas.openxm…

[小试牛刀-习题练]《计算机组成原理》之计算机系统概述【详解过程】

【计算机系统概述】 1、【冯诺伊曼结构】计算机中数据采用二进制编码表示&#xff0c;其主要原因是&#xff08;D&#xff09; I、二进制运算规则简单II、制造两个稳态的物理器件较为容易III、便于逻辑门电路实现算术运算 A.仅I、Ⅱ B.仅I、Ⅲ C.仅Ⅱ、Ⅲ D. I、Ⅱ、Ⅲ I…

redis 单节点数据如何平滑迁移到集群中

目的 如何把一个redis单节点的数据迁移到 redis集群中 方案&#xff1a; 使用命令redis-cli --cluster import 导入数据至集群 --cluster-from <arg>--cluster-from-user <arg> 数据源用户--cluster-from-pass <arg> 数据源密码--cluster-from-askpass--c…

Linux开发讲课20--- QSPI

SPI 是英语 Serial Peripheral interface 的缩写&#xff0c;顾名思义就是串行外围设备接口&#xff0c;一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚&#xff0c;为 PCB 的布局上节省空间…

《SpringBoot+Vue》Chapter04 SpringBoot整合Web开发

返回JSON数据 默认实现 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>在springboot web依赖中加入了jackson-databind作为JSON处理器 创建一个实体类对象…

为什么Modbus链接/从机不通?From 摩尔信使MThings

为了回应用户平日里关于摩尔信使&#xff08;MThings&#xff09;使用过程中最常见的问题&#xff0c;包括“网络链接连不上”、“为什么不能增加串口”和“为什么从机不通”&#xff0c;我们在此统一介绍解决方法。 1、具备哪些通信能力 支持串口和网络两种通信方式。 需要…