一. 链表简单介绍

链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)[1],通常链表的头被称为head,尾部一般用null表示。【图自[1]】

链表的类型有单链表,双链表,循环链表等。数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。链表是通过指针域的指针链接在内存中各个节点。

二. 链表的代码实现

leetcode中对单向链表的典型实现

  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; }}

三. leetcode&牛客实例

1. leetcode206 && nowcoderBM1 反转链表

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

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

(1)数组(list)方法:全部将值取出再重新赋值 

class Solution {public ListNode reverseList(ListNode head) {//1.全部取值重新赋值return reverseList1(head);}public ListNode reverseList1(ListNode head){if(head == null) return null;LinkedList<Integer> list = new LinkedList<>();while(head != null){list.add(head.val);head = head.next;}ListNode new_head = new ListNode(list.removeLast());ListNode cur = new_head;ListNode temp;while(!list.isEmpty()){temp = new ListNode(list.removeLast());cur.next = temp;cur = temp;}return new_head;}
}

(2)原地反转

        原地反转需要三个指针,三个指针在这里分别定义为tail,middle,pre。

class Solution {public ListNode reverseList(ListNode head) {//2.原地反转return reverseList2(head);}public ListNode reverseList2(ListNode head){if(head == null) return null;ListNode tail = head;if(tail.next == null) return tail;ListNode middle = head.next;ListNode pre = middle.next;tail.next = null;while(middle.next != null){middle.next = tail;tail = middle;middle = pre;pre = pre.next;}middle.next = tail;return middle;}
}

(3)构建新链表(头插法)

class Solution {public ListNode reverseList(ListNode head) {//3.构建新链表return reverseList3(head);}public ListNode reverseList3(ListNode head){if(head == null || head.next == null) return head;ListNode new_head = new ListNode(head.val);new_head.next = null;ListNode temp = head.next;ListNode cur = new_head;while(temp.next != null){head = temp.next;temp.next = cur;cur = temp;temp = head;}temp.next = cur;return temp;}
}

(4)递归

class Solution {public ListNode reverseList(ListNode head) {//5.递归return reverseList5(head);}public ListNode reverseList5(ListNode head) {// 1. 递归终止条件if (head == null || head.next == null) {return head;}ListNode p = reverseList(head.next);head.next.next = head;head.next = null;return p;}
}

2. leetcode21 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

 双指针

class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode p1 = list1;ListNode p2 = list2;ListNode new_pre = new ListNode(0);ListNode cur = new_pre;while(p1 != null && p2 != null){if(p1.val < p2.val){cur.next = p1;cur = cur.next;p1 = p1.next;}else{cur.next = p2;cur = cur.next;p2 = p2.next;}}if(p1 == null){cur.next = p2;}if(p2 == null){cur.next = p1;}return new_pre.next;}
}

递归

class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if(list1 == null){return list2;}else if(list2 == null){return list1;}else if(list1.val < list2.val){list1.next = mergeTwoLists(list1.next,list2);return list1;}else{list2.next = mergeTwoLists(list1,list2.next);return list2;}}
}

3. leetcode83 删除链表中的重复元素

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

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

class Solution {public ListNode deleteDuplicates(ListNode head) {if(head == null) return null;ListNode tail = head;ListNode pre = tail.next;while(pre != null){if(tail.val == pre.val){pre = pre.next;}else{tail.next = pre;tail = pre;pre = pre.next;}}if(tail.next == null) return head;tail.next = null;return head;}
}
class Solution {public ListNode deleteDuplicates(ListNode head) {if(head == null) {return null;}ListNode t1 = head;ListNode t2 = head.next;while(t2 != null){if(t1.val == t2.val){t1.next = t2.next;t2 = t1.next;}else{t1 = t2;t2 = t2.next;}}return head;}}
class Solution {public ListNode deleteDuplicates(ListNode head) {ListNode cur = head;while(cur != null && cur.next != null) {if(cur.val == cur.next.val) {cur.next = cur.next.next;} else {cur = cur.next;}}return head;}
}

4. leetcode141 环形链表

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

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

HashSet方法:

public class Solution {public boolean hasCycle(ListNode head) {HashSet<ListNode> list = new HashSet<>();while(head != null){if(list.contains(head)){return true;}else{list.add(head);head = head.next;}}return false;}
}

双指针 :

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

5. leetcode234 回文链表

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

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

双指针+栈

class Solution {public boolean isPalindrome(ListNode head) {if(head.next == null) return true;ListNode slow = head;ListNode fast = head;Deque<Integer> list = new ArrayDeque<>();while(fast != null && fast.next != null){list.push(slow.val);slow = slow.next;fast = fast.next.next;} if(fast == null){while(slow != null){if(slow.val != list.pop()){return false;}slow = slow.next;}}else{slow = slow.next;while(slow != null){if(slow.val != list.pop()){return false;}slow = slow.next;}}return true;}
}

双指针+反转

class Solution {public boolean isPalindrome(ListNode head) {if(head.next == null) return true;ListNode slow = head;ListNode fast = head;ListNode tail = null;while(fast != null && fast.next != null){//slow = slow.next;fast = fast.next.next;ListNode temp = slow;slow = slow.next;temp.next = tail;tail = temp;} if(fast != null){slow = slow.next;}while(slow != null){if(slow.val != tail.val){return false;}slow = slow.next;tail = tail.next;}return true;}
}

6. leetcode92 反转链表II

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

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

class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {ListNode dummyhead = new ListNode(0);dummyhead.next = head;ListNode tail = dummyhead;ListNode pre = dummyhead.next;for(int i = 0; i < left-1; i++){tail = tail.next;pre = pre.next;}for(int i = 0; i < right-left;i++){ListNode temp = pre.next;pre.next = temp.next;// temp.next = pre;// tail.next = temp;temp.next = tail.next;tail.next = temp;}return dummyhead.next;}
}

参考来源:

【1】代码随想录 Carl 链表

【2】leetcode  木已成舟 Java-双指针-头插法

Java-数据结构-链表<一>相关推荐

  1. 猴子选大王 java_基于java数据结构链表写的猴子选大王

    [实例简介] 基于java数据结构链表写的猴子选大王,其实就是一个约瑟夫环问题,采用java数据结构链表写的.有点小问题.当输入一只猴子,报数为1时删除会出错.没有实现动态显示猴子的添加和删除. [实 ...

  2. Java数据结构链表面试题 作者:哇塞大嘴好帥(哇塞大嘴好帅) --持续更新

    作者:哇塞大嘴好帥(哇塞大嘴好帅) Java数据结构链表面试题 4.1.查询链表有效数据个数 //判断有效数据个数 public int validDate(){//创建临时变量NodeDate no ...

  3. java数据结构-链表详解

    文章目录 1.数据结构-链表详解 1.1单链表 1.1.1单链表节点的尾部添加 1.1.2单链表节点的自动排序添加 1.1.3单链表节点的修改 1.1.4单链表节点的删除 1.2单链表面试题 1.2. ...

  4. Java数据结构--链表

    public interface Predecessor<E> {//定义接口 用于实现多态public ListNode<E> getNext(); public void ...

  5. java数据结构 -链表 -获取有效节点个数,单链表中倒数k个节点

    // 1.获取到单链表的节点的个数(如果有头结点,不统计头结点)public static int getLength(HeroNode head){if (head.next == null){re ...

  6. 【Java数据结构[链表--单向链表]】

    单向链表 链表是以节点的方式来存储的,是链式存储 每个节点包含一个数据域用来保存当前节点的数据,一个next域用于指向下一个节点 单链表结构示意图: 单链表内存示意图: 代码实现: //链表 clas ...

  7. Java数据结构——链表

    目录 方法一 方法二 问题一:求单链表中有效节点的个数 问题二:查找单链表中的倒数第k个结点 问题三:单链表的反转 问题三:从尾到头打印单链表 [方式1:反向遍历 . 方式2:Stack栈] 问题四: ...

  8. Java数据结构 -- 链表

    生活中的链表 链表其实是一个一环扣一环的东西,最简单明了的就是我们的链子了,它就是一个一环扣一环的东西 链表介绍 链表在内存中的图解可以用下图来表示 链表是以节点的方式存储,是一个链式存储. 每个节点 ...

  9. Java数据结构和算法(七)——链表

    前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷.在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且数组在创建后,其大小是固定了,设置的过大会造 ...

  10. java双链表基本方法_Java数据结构之双端链表原理与实现方法

    本文实例讲述了Java数据结构之双端链表原理与实现方法.分享给大家供大家参考,具体如下: 一.概述: 1.什么时双端链表: 链表中保持这对最后一个连点引用的链表 2.从头部插入 要对链表进行判断,如果 ...

最新文章

  1. Nginx及其架构设计
  2. pyhanlp 提取关键词、自动摘要
  3. [置顶] CopyU!v2插件合集 [2013年7月18日更新]
  4. bat 连续读取两行_Redis底层数据结构解析(BAT大厂必问)
  5. net framework 3.5 安装错误_PageAdmin CMS建站系统报http403错误的解决方案
  6. registered php streams sqlsrv,tp5与SQL Server的爱恨情仇(1)
  7. C语言程序设计第四次作业
  8. MyEclipse编码设置
  9. ImportError: No module named 'requests.packages.urllib3'
  10. 中标麒麟linux系统安装打印机_国产操作系统中标麒麟系统安装教程
  11. (30)tensorboard ValueError: Duplicate plugins for name projector
  12. web前端开发教学视频,web前端开发职业
  13. MATLABR2012a如何激活
  14. vue 数组中的元素 渲染到一行
  15. FPGAi2c总线调试M24LC04B
  16. windows 10 专业版构建虚拟机业务Hyper-V
  17. 安卓设置keychain_IOS的keychain的三种使用方法
  18. ‘org.springframework.messaging.simp.SimpMessagingTemplate‘ that could not be found.
  19. 优盘制作服务器引导盘,USBOS V3.0彪悍版U盘启动盘制作工具-用于PC/工控机/服务器/Surface/Mac...
  20. 【安全与协议】使用crypto.js进行加密详解

热门文章

  1. 一块猪肉脯花2年升级,良品铺子打的什么“算盘”?
  2. python实现基于RPC协议的接口自动化测试
  3. 纯css阴阳旋转js特效代码
  4. 写一段问候即将做手术的人的话
  5. 三星S5368 ZMKL1官方ROM包下载+刷机教程
  6. Python人脸识别和对比
  7. 【学习笔记】计算机网络 第八章 无线局域网(WLAN)
  8. java 密码正则_强密码的正则表达式
  9. 一夫三妻!全家福曝光 合作写书三个人的爱/组图
  10. 《Python 黑帽子》学习笔记 - 准备 - Day 1