链表

  • 链表
    • 1.移除链表元素
      • 203.移除链表元素
      • 707.设计链表
    • 2.反转链表
      • 206.反转链表
    • 3.两两交换链表中的节点
      • 24.两两交换链表中的节点
    • 4.删除链表中的倒数第N个节点
      • 19.删除链表的倒数第N个节点
    • 5.链表相交
      • 07.链表相交
    • 6.环形链表
      • 141.环形链表
      • 142.环形链表II

链表

1.移除链表元素

203.移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

示例 1:

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

思路1:原链表删除
要考虑两种情况,
如果要删除的元素是头节点,那么需要将头节点指向下一个。如果头节点不是目标元素。要想删除一个节点,必须知道这个节点的上一个节点,然后跳跃删除。

  public ListNode removeElements1(ListNode head, int val) {while(head!=null&&head.val==val) {head=head.next;}ListNode cur=head;while(cur!=null) {while(cur.next!=null&&cur.next.val==val) {cur.next=cur.next.next;}cur=cur.next;}return head;}

思路2:虚拟头节点
为链表新建一个头节点,这样就不用考虑头节点是不是要删除的元素了,直接进行跳跃删除。

 public ListNode removeElements(ListNode head, int val) {if(head==null) {return head;}ListNode dummy=new ListNode(-1,head);ListNode pre=dummy;ListNode cur=head;while(cur!=null) {if(cur.val==val) {pre.next=cur.next;}else {pre=cur;}cur=cur.next;}return dummy.next;}

707.设计链表

设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

在链表类中实现这些功能:

get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

思路:
这道题实现的功能就比较多了,要注意控制节点的位置时要新声明一个节点,不能用head来操作,否则链表位置会乱套。思想是挺简单的,但是实现起来还是有很多坑的。

class ListNode { //定义一个链表结构,包括数值域,指针域int val;ListNode next;ListNode() {}ListNode(int val) {this.val = val;}ListNode(int val, ListNode next) {this.val = val;this.next = next;}
}public class MyLinkedList {int size;ListNode head;public MyLinkedList() {//链表初始化,注意这里声明了一个头节点,和没有头节点的操作就大不相同head = new ListNode(0);size = 0;}public int get(int index) {ListNode cur = head;  //遍历位置信息时要新声明一个节点,不能直接操作headif (index < 0 || index > size - 1) {return -1;}while (index != 0) {cur = cur.next;index--;}return cur.next.val;}public void addAtHead(int val) { //在头部添加一个节点ListNode newNode = new ListNode(val);newNode.next = head.next;head.next = newNode;size++;}public void addAtTail(int val) { //在尾部添加一个节点,只要按顺序找到最后一个指针就行了 ListNode newNode = new ListNode(val);ListNode cur = head;while (cur.next != null) {cur = cur.next;}cur.next = newNode;size++;}public void addAtIndex(int index, int val) {if (index > size) {return;}ListNode newNode = new ListNode(val);if (index <= 0) {  //在头节点增加newNode.next = head.next;head.next = newNode;size++;} else {ListNode cur = head;while (index >= 1) { //在其他的位置增加,记好数就ok了cur = cur.next;index--;}newNode.next = cur.next;cur.next = newNode;size++;}}public void deleteAtIndex(int index) {ListNode cur = head;if (index < 0 || index > size - 1) {return;}if (index == 0) {head = head.next;}while (index >= 1) {  cur = cur.next;index--;}cur.next = cur.next.next; //找到目标位置直接跳步删除即可size--;}public static void main(String[] args) {MyLinkedList myLinkedList = new MyLinkedList();myLinkedList.addAtHead(2);// myLinkedList.addAtTail(3);myLinkedList.addAtIndex(0, 1);System.out.println(myLinkedList.get(1));// myLinkedList.deleteAtIndex(1);// System.out.println(myLinkedList.get(1));}
}

2.反转链表

206.反转链表

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

示例 1:

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

思路1:正常反转
先保存了头指针的下一个节点,然后让头指针指向pre,然后pre和头指针都往后移。第二次看这个链表反转有很大的收获,之前我一直以为反转是要重新建一条链表,现在再看,知识需要把head.next的指针指向前边就可以了。

class Solution {public ListNode reverseList(ListNode head) {ListNode next=null;ListNode pre=null;while(head!=null){next=head.next;head.next=pre;pre=head;head=next;}return pre;}
}

思路2:递归反转
思路和正常反转一样,只不过是套了一个递归函数,把后边那个语句换成递归函数就可以了。

public ListNode reverseList(ListNode head) {return reverse(head , null);}public ListNode reverse(ListNode head,ListNode pre) {if(head==null) {return pre ;}ListNode next=null;next=head.next;head.next=pre;return reverse(next,head);}

3.两两交换链表中的节点

24.两两交换链表中的节点


思路:
判断好结束条件,然后申请两个临时指针,分别保存好下面两个节点的元素,然后交换即可。

 public ListNode swapPairs(ListNode head) {ListNode dummy=new ListNode(0);//创建一个虚拟头节点dummy.next=head;ListNode cur=dummy; //进行操作的指针ListNode temp1;  //两个临时指针ListNode temp2;while(cur.next!=null&&cur.next.next!=null) {//判断结束条件,链表节点是奇数还是偶数的情况都包含进去了temp1=cur.next;//保存下一个节点的指针temp2=cur.next.next;//保存第二个节点的指针cur.next=temp2;temp1.next=temp2.next;temp2.next=temp1;cur=temp1; //移动cur指针,保证它在要操作的节点的前一个节点}return dummy.next;}

4.删除链表中的倒数第N个节点

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


思路:
设立两个快慢指针,先让快指针走n+步,当快指针指向链表尾节点的时候,此时慢指针恰好走到要删除节点的前一个节点,此时对慢指针进行删除即可。设立虚拟头节点的好处是,避免了空指针异常。

 public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy=new ListNode(0);dummy.next=head;//设立快慢指针,先让快指针移动n+1不,然后快慢指针同时移动ListNode  fast=dummy;ListNode slow=dummy;n++;while(n--!=0&&fast!=null) {fast=fast.next;}while(fast!=null) {fast=fast.next;slow=slow.next;}slow.next=slow.next.next;return dummy.next;}

5.链表相交

07.链表相交


思路:
两个指针,当着两个指针走向尽头时,然后转向另一个链表的头节点,直到这两个链表相遇,因为这两个节点都走了同样的长度。

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA==null||headB==null) {return null;}ListNode pA=headA;ListNode pB=headB;while(pA!=pB) {pA=pA==null?headB:pA.next;pB=pB==null?headA:pB.next;}return pA;}

6.环形链表

141.环形链表


思路:
一个快指针,一个慢指针,当快指针和慢指针相遇的话一定会有环。

  public boolean hasCycle(ListNode head) {if(head==null) {return false;}ListNode slow=head;ListNode fast=head;if(head.next!=null) {fast=head.next;}while(fast.next!=null&&fast.next.next!=null) {if(fast==slow) {return true;}slow=slow.next;fast=fast.next.next;}return false;}

142.环形链表II


思路:
和第一个不同的是,这个要返回环形链表的交点了。
设头节点到成环节点的距离为x,设成环节点到相遇节点的距离为y,设相遇节点到成环节点的距离为z。慢指针移动的距离为x+y.快指针走的节点数为x+n(y+z)。
因为快指针速度是慢指针的二倍,所以有2(x+y)=x+n(y+z)
整理得x=n(y+z)-y=(n-1)(y+z)+z。

当n=1的时候有x=z。当n不等于1的时候,说明快指针在环里移动了好几圈,也不影响题目
此时代表index1指针在环里多转了n-1圈,才遇到的index2,相遇节点也是入环的初始位置。

  public ListNode detectCycle(ListNode head) {if(head==null) {return null;}ListNode slow=head;ListNode fast=head;while(fast!=null&&fast.next!=null) {slow=slow.next;fast=fast.next.next;if(fast==slow) {ListNode index1=fast;ListNode index2=head;while(index1!=index2) {index1=index1.next;index2=index2.next;}return index1;}}return null;}

LeetCode分类刷题----链表篇相关推荐

  1. leetcode分类刷题笔记

    leetcode分类刷题笔记--基于python3 写在前面 1.做题如果实在想不出时间复杂度比较优的解法,可以先写出暴力解法,尝试在其基础上优化 2.排序.双指针.二分等--经常可以优化时间复杂度 ...

  2. leetcode分类刷题

    1. 数组 数组是基本的数据结构,面试中考察数组的题目一般在思维上并不复杂,主要是考查面试者对代码的掌控能力. 数组下标都是从0开始 数组在内存空间的地址是连续的 题目: easy 704. 二分查找 ...

  3. leetcode刷题链表

    leetcode刷题链表 反转链表Ⅱ 题目描述将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1).例如: 给出的链表为9 ...

  4. leetcode每日刷题计划-简单篇day8

    leetcode每日刷题计划-简单篇day8 今天是纠结要不要新买手机的一天QAQ想了想还是算了吧,等自己赚钱买,加油 Num 70 爬楼梯 Climbing Stairs class Solutio ...

  5. LeetCode代码刷题(17~24)

    目录 17. 电话号码的字母组合 18. 四数之和 19. 删除链表的倒数第 N 个结点 20. 有效的括号 21. 合并两个有序链表 22. 括号生成 23. 合并K个升序链表 24. 两两交换链表 ...

  6. 【Leetcode】 刷题之路1(python)

    leetcode 刷题之路1(python) 看到有大佬总结了一些相关题目,想着先刷一类. 1.两数之和 15.三数之和 16.最接近的三数之和 11.盛最多的水 18.四数之和 454.四数相加II ...

  7. i春秋python_I春秋刷题 WEB篇

    I春秋刷题 WEB篇 一.爆破-1 题目内容:flag就在某六位变量中. include "flag.php"; $a = @$_REQUEST['hello']; if(!pre ...

  8. C#LeetCode刷题-链表

    链表篇 # 题名 刷题 通过率 难度 2 两数相加   29.0% 中等 19 删除链表的倒数第N个节点   29.4% 中等 21 合并两个有序链表 C#LeetCode刷题之#21-合并两个有序链 ...

  9. LeetCode刷题——链表OJ(历时三天,万字博客,十一道经典题,带你手撕链表)

    知之愈明,则行之愈笃:行之愈笃,则知之益明. 学完链表,我们不得刷刷题增进对链表的认识?今天博主选取十一道经典链表题,从刷题者的角度剖析重点和易错点,讲解最简单的方法,文章内附题目和题目链接,重点内容 ...

最新文章

  1. 2022-2028年中国硅质原料行业全景调研及投资前景展望报告
  2. 在同一台电脑上同时安装Python2和Python3
  3. 职场中有哪些沟通的小技巧?
  4. 数学编程:经典数学编程案例之斐波那契:斐波那契数列的简介、代码实现、exe程序应用(斐波纳契时钟设计)之详细攻略
  5. `Caused by: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
  6. Scala偏函数使用示例
  7. c# 多线程 执行事件 并发_C#.NET Thread多线程并发编程学习与常见面试题解析-1、Thread使用与控制基础...
  8. Google Analytics(分析)
  9. 您已关注公众号满1年,诚邀您免费加入金融学习交流群!
  10. python 遍历文件夹
  11. cc2500的register操作
  12. c++实现串口功能之termios.h头文件研读<二>
  13. gridview的sort_Gridview自动排序功能的实现
  14. 现场总线->无线网络的技术->泛在网络
  15. 买笔记本电脑主要看什么?
  16. ADS-B及雷达显示终端8.0
  17. 火狐浏览器的全屏兼容问题 allowfullscreen=true
  18. Dashgo D1使用手册
  19. Vue3获取地址栏参数
  20. 逆向学习fastjson反序列化始

热门文章

  1. ebcdic java_在Java中将EBCDIC转换为ASCII
  2. win10 python3.5.2下安装facenet
  3. 生产实践中的经典算法(四)-BitMap
  4. professional issue复习
  5. 神操作 用 Python 操作 xmind 绘制思维导图
  6. php中文字符乱码,如何解决php中文字符乱码问题
  7. php返回值乱码,php中文返回乱码怎么办
  8. kafka之主题操作kafka-topics命令
  9. mysql怎么对月份进行统计_MySQL如何按月份统计数据详解(转)
  10. 2019-nCoV肺炎疫情同程查询-完整提供 Demo 代码示例及数据专业且全面的 API 查询接口