前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java基础–单链表的实现[通俗易懂]

Java基础–单链表的实现[通俗易懂]

作者头像
全栈程序员站长
发布于 2022-07-01 13:11:42
发布于 2022-07-01 13:11:42
43000
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

Java内部也有自己的链表–LinkedList,但是我们今天不是讨论LinkedList,而是自己来实现一个单链表,包括简单的增删查改:

  • 单链表的结构
  • 单链表的基本操作
  • 虚拟头结点的使用

整个类的设计如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Linked <T>{
	
	private class Node{
		private T t;
		private Node next;
		public Node(T t,Node next){
			this.t = t;
			this.next = next;
		}
		public Node(T t){
			this(t,null);
		}
	}
	private Node head;    		//头结点
	private int size;			//链表元素个数
	//构造函数
	public Linked(){
		this.head = null;
		this.size = 0;
	}
}

单链表的结构

一种链式存取的数据结构,单链表中的数据是以结点的形式存在,每一个结点是由数据元素和下一个结点的存储的位置组成。单链表与数组相比的最大差别是:单链表的数据元素存放在内存空间的地址是不连续的,而数组的数据元素存放的地址在内存空间中是连续的,这也是为什么根据索引无法像数组那样直接就能查询到数据元素。

[单链表结构图]

链表存储的结点

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private class Node{
		private T t;
		private Node next;
		public Node(T t,Node next){
			this.t = t;
			this.next = next;
		}
		public Node(T t){
			this(t,null);
		}
}

链表的基本操作

包括链表的增删查改,以及判别某结点是否存在链表中

链表结点的增加

进行结点的添加的时候,是根据索引来进行操作的,由于成员变量size记录了当前链表的元素个数,进行某个索引位置的结点插入就会很方便了。先找到该目标索引的前一个结点,记录为pre,把要插入的结点node的下一个结点node.next指向pre的下一个结点pre.next;再把pre.next指向node结点。如果先进行pre.next指向要插入的结点,再进行node.next指向pre.next的话,无疑是要插入的结点自己指向了自己,无法连接上整个链表,在链表的操作中,有时候顺序的执行会带来不一样的结果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//链表头部添加元素
	public void addFirst(T t){
		Node node = new Node(t);	//节点对象
		node.next = this.head;
		this.head = node;
		//this.head = new Node(e,head);等价上述代码
		this.size++;
	}
	//向链表尾部插入元素
	public void addLast(T t){
		this.add(t, this.size);
	}
	//向链表中间插入元素
	public void add(T t,int index){
		if (index <0 || index >size){
			throw new IllegalArgumentException("index is error");
		}
		if (index == 0){
			this.addFirst(t);
			return;
		}
		Node preNode = this.head;
		//找到要插入节点的前一个节点
		for(int i = 0; i < index-1; i++){
			preNode = preNode.next;
		}
		Node node = new Node(t);
		//要插入的节点的下一个节点指向preNode节点的下一个节点
		node.next = preNode.next;
		//preNode的下一个节点指向要插入节点node
		preNode.next = node;
		this.size++;
	}
链表结点的删除
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//删除链表元素
	public void remove(T t){
		if(head == null){
			System.out.println("无元素可删除");
			return;
		}
		//要删除的元素与头结点的元素相同
		while(head != null && head.t.equals(t)){
			head = head.next;
			this.size--;
		}
		/**
		 * 上面已经对头节点判别是否要进行删除
		 * 所以要对头结点的下一个结点进行判别
		 */
		Node cur = this.head;
		while(cur != null && cur.next != null){
			if(cur.next.t.equals(t)){
				this.size--;
				cur.next = cur.next.next;
			}
			else cur = cur.next;
		}
		
	}

在进行链表的结点删除时候,要分情况讨论:

当要删除的结点位于头结点的时候: 如下图要删除的元素1的结点位于头结点,先进行while判断头结点是否为null且判断该结点的元素是否为要删除的元素,如果是把head指向head.next即可,直接跳过头结点,直到头结点不是要删除的元素就结束循环。

[要删除的元素1位于头结点]

当要删除的结点不在头结点的时候:如下图删除元素为3的结点,由于上面已经判断了头结点不是要删除的元素,所以我们从头结点的下一个结点开始循环,即cur.next,当cur.next是要被删除的元素时,直接cur.next = curr.next.next就能直接跳过cur.next,断开。 [要删除结点的元素为3的结点]

删除链表的头结点的元素和删除链表的尾结点的元素

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//删除链表第一个元素
	public T removeFirst(){
		if(this.head == null){
			System.out.println("无元素可删除");
			return null;
		}
		Node delNode = this.head;
		this.head = this.head.next;
		delNode.next =null;
		this.size--;
		return delNode.t;
	}
	//删除链表的最后一个元素
	public T removeLast(){
		if(this.head == null){
			System.out.println("无元素可删除");
			return null;
		}
		//只有一个元素
		if(this.getSize() == 1){
			return this.removeFirst();
		}
		Node cur = this.head;	//记录当前结点
		Node pre = this.head;	//记录要删除结点的前一个结点
		while(cur.next != null){
			pre = cur;
			cur = cur.next;
		}
		pre.next = cur.next;
		this.size--;
		return cur.t;
	}

经过上面在进行链表的结点删除的时候,会发现在删除的过程中很麻烦,还得考虑头结点(因为我们在删除结点的时候,都是先找到待删除结点del的前一个结点pre,然后直接进行跳过操作,即pre.next = pre.next.next,但是删除结点头结点的时候就无法操作),给我们添加了麻烦,为此我们可以给链表添加一个虚拟的头结点,说白了就是重新new一个结点对象,该结点对象的下一个结点指向了我们之前的头结点,让我们在删除结点的时候,无须再考虑之前的头结点了!

虚拟头结点删除链表元素的实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//加入虚拟头结点的链表进行删除
	public void removeElt(T t){
		//构造虚拟头结点,并且下一个结点指向head
		Node dummy = new Node(t,this.head);
		//声明结点指向虚拟头结点
		Node cur = dummy;
		//从虚拟头结点的下一个结点开始遍历
		while(cur.next != null){
			if(cur.next.t.equals(t)){ 
				cur.next = cur.next.next;
				this.size--;
			}
			else cur = cur.next;
		}
		//去除虚拟头结点
		this.head = dummy.next;
	}
使用虚拟头结点进行链表的插入

刚开始那部分的结点添加是基于索引的情况实现,当我们无法知道一个结点的位于链表的哪个位置时候,只知道要插入在某个元素的前面,下面的代码基于上述情况实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	/**
	 * 
	 * @param t:插入在t元素的位置
	 * @param des:要插入的元素
	 */
	public void insert(T t,T des){
		//构造虚拟头结点,并且下一个结点指向head
		Node dummy = new Node(null,this.head);
		//构造要插入的结点
		Node dNode = new Node(des);
		//声明变量cur指向虚拟头结点
		Node cur = dummy;
		while(cur.next != null){
			if(cur.next.t.equals(t)){ 
				dNode.next = cur.next;
				cur.next = dNode;
				this.size++;
				break;
			}
			else cur = cur.next;
		}
		this.head = dummy.next;
	}

查找某个元素是否在链表的结点上

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//链表中是否包含某个元素
	public boolean contains(T t){
		Node cur = this.head;
		while(cur != null){
			if(cur.t.equals(t)){
				return true;
			}
			else cur = cur.next;
		}
		return false;
	}

完整的代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package LinkedList;

public class Linked <T>{
	
	private class Node{
		private T t;
		private Node next;
		public Node(T t,Node next){
			this.t = t;
			this.next = next;
		}
		public Node(T t){
			this(t,null);
		}
	}
	private Node head;    		//头结点
	private int size;			//链表元素个数
	//构造函数
	public Linked(){
		this.head = null;
		this.size = 0;
	}
	
	//获取链表元素的个数
	public int getSize(){
		return this.size;
	}
	//判断链表是否为空
	public boolean isEmpty(){
		return this.size == 0;
	}
	//链表头部添加元素
	public void addFirst(T t){
		Node node = new Node(t);	//节点对象
		node.next = this.head;
		this.head = node;
		// this.head = new Node(e,head);等价上述代码
		this.size++;
	}
	//向链表尾部插入元素
	public void addLast(T t){
		this.add(t, this.size);
	}
	//向链表中间插入元素
	public void add(T t,int index){
		if (index <0 || index >size){
			throw new IllegalArgumentException("index is error");
		}
		if (index == 0){
			this.addFirst(t);
			return;
		}
		Node preNode = this.head;
		//找到要插入节点的前一个节点
		for(int i = 0; i < index-1; i++){
			preNode = preNode.next;
		}
		Node node = new Node(t);
		//要插入的节点的下一个节点指向preNode节点的下一个节点
		node.next = preNode.next;
		//preNode的下一个节点指向要插入节点node
		preNode.next = node;
		this.size++;
	}
	//删除链表元素
	public void remove(T t){
		if(head == null){
			System.out.println("无元素可删除");
			return;
		}
		//要删除的元素与头结点的元素相同
		while(head != null && head.t.equals(t)){
			head = head.next;
			this.size--;
		}
		/**
		 * 上面已经对头节点判别是否要进行删除
		 * 所以要对头结点的下一个结点进行判别
		 */
		Node cur = this.head;
		while(cur != null && cur.next != null){
			if(cur.next.t.equals(t)){
				this.size--;
				cur.next = cur.next.next;
			}
			else cur = cur.next;
		}
		
	}
	//删除链表第一个元素
	public T removeFirst(){
		if(this.head == null){
			System.out.println("无元素可删除");
			return null;
		}
		Node delNode = this.head;
		this.head = this.head.next;
		delNode.next =null;
		this.size--;
		return delNode.t;
	}
	//删除链表的最后一个元素
	public T removeLast(){
		if(this.head == null){
			System.out.println("无元素可删除");
			return null;
		}
		//只有一个元素
		if(this.getSize() == 1){
			return this.removeFirst();
		}
		Node cur = this.head;	//记录当前结点
		Node pre = this.head;	//记录要删除结点的前一个结点
		while(cur.next != null){
			pre = cur;
			cur = cur.next;
		}
		pre.next = cur.next;
		this.size--;
		return cur.t;
	}
	//链表中是否包含某个元素
	public boolean contains(T t){
		Node cur = this.head;
		while(cur != null){
			if(cur.t.equals(t)){
				return true;
			}
			else cur = cur.next;
		}
		return false;
	}
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		Node cur = this.head;
		while(cur != null){
			sb.append(cur.t+"->");
			cur = cur.next;
		}
		sb.append("NULL");
		return sb.toString();
	}
	
	public static void main(String[] args) {
		Linked<Integer> linked = new Linked();
		for(int i = 0; i < 10; i++){
			linked.addFirst(i);
			System.out.println(linked);
		}
		linked.addLast(33);
		linked.addFirst(33);
		linked.add(33, 5);
		System.out.println(linked);
		linked.remove(33);
		System.out.println(linked);
		System.out.println("删除第一个元素:"+linked.removeFirst());
		System.out.println(linked);
		System.out.println("删除最后一个元素:"+linked.removeLast());
		System.out.println(linked);
	}
}

总结:学链表是一种痛苦,但是痛苦并快乐着,希望能够坚持下去,把链表的全家桶都学习了,而不是这么简单的增加和删除。上述如有说的不对的地方欢迎指正!下篇文章将进行用链表实现栈和队列。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/130306.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
2022-06-25:给定一个正数n, 表示有0~n-1号任务, 给定一个长度为n的数组time,time[i]表示i号任务做完的时间, 给定一个二维数组mat
2022-06-25:给定一个正数n, 表示有0~n-1号任务,给定一个长度为n的数组time,timei表示i号任务做完的时间,给定一个二维数组matrix,matrixj = {a, b} 代表:a任务想要开始,依赖b任务的完成,只要能并行的任务都可以并行,但是任何任务只有依赖的任务完成,才能开始。返回一个长度为n的数组ans,表示每个任务完成的时间。输入可以保证没有循环依赖。来自美团。3.26笔试。答案2022-06-25:拓扑排序基础上做动态规划。代码用rust编写。代码如下:fn main() {
福大大架构师每日一题
2022/06/25
3910
2022-06-25:给定一个正数n, 表示有0~n-1号任务, 给定一个长度为n的数组time,time[i]表示i号任务做完的时间, 给定一个二维数组mat
2022-06-06:大妈一开始手上有x个鸡蛋,她想让手上的鸡蛋数量变成y, 操作1 : 从仓库里拿出1个鸡蛋到手上,x变成x+1个
操作2 : 如果手上的鸡蛋数量是3的整数倍,大妈可以直接把三分之二的鸡蛋放回仓库,手里留下三分之一。
福大大架构师每日一题
2022/06/06
1750
2022-06-06:大妈一开始手上有x个鸡蛋,她想让手上的鸡蛋数量变成y, 操作1 : 从仓库里拿出1个鸡蛋到手上,x变成x+1个
2022-09-27:给定一个棵树, 树上每个节点都有自己的值,记录在数组nums里, 比如nums[4] = 10,表示4号点的值是10, 给定树上的每一条边
请问怎么分割,能让最终的:三个部分中最大的异或值 - 三个部分中最小的异或值,最小。
福大大架构师每日一题
2022/09/27
5160
2022-09-27:给定一个棵树, 树上每个节点都有自己的值,记录在数组nums里, 比如nums[4] = 10,表示4号点的值是10, 给定树上的每一条边
2022-11-04:给定一个正数n,表示有多少个节点 给定一个二维数组edges,表示所有无向边 edges[i] = {a, b} 表示a到b有一条无向边
2022-11-04:给定一个正数n,表示有多少个节点 给定一个二维数组edges,表示所有无向边 edgesi = {a, b} 表示a到b有一条无向边 edges一定表示的是一个无环无向图,也就是树结构 每个节点可以染1、2、3三种颜色。 要求 : 非叶节点的相邻点一定要至少有两种和自己不同颜色的点。 返回一种达标的染色方案,也就是一个数组,表示每个节点的染色状况。 1 <= 节点数量 <= 10的5次方。 来自米哈游。 答案2022-11-04: 生成图,选一个头节点,深度优先染色。 代码用rust编
福大大架构师每日一题
2022/11/04
4580
2022-11-04:给定一个正数n,表示有多少个节点 给定一个二维数组edges,表示所有无向边 edges[i] = {a, b} 表示a到b有一条无向边
2023-09-03:用go编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数 n 和一个长度为
2023-09-03:用go语言编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1
福大大架构师每日一题
2023/09/04
2220
2023-09-03:用go编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数 n 和一个长度为
2022-09-05:作为国王的统治者,你有一支巫师军队听你指挥。 :给你一个下标从 0 开始的整数数组 strength , 其中 strength[i] 表
请你返回 所有 巫师组的 总 力量之和。由于答案可能很大,请将答案对 109 + 7 取余 后返回。
福大大架构师每日一题
2022/09/05
2150
2022-09-05:作为国王的统治者,你有一支巫师军队听你指挥。 :给你一个下标从 0 开始的整数数组 strength , 其中 strength[i] 表
2023-03-20:给定一个无向图,保证所有节点连成一棵树,没有环,给定一个正数n为节点数,所以节点编号为0~n-1,那么就一
为了解决此问题,我们可以使用搜索和动态规划技术进行优化,下面将详细介绍两种算法的实现方法。
福大大架构师每日一题
2023/06/08
2920
2023-03-20:给定一个无向图,保证所有节点连成一棵树,没有环,给定一个正数n为节点数,所以节点编号为0~n-1,那么就一
2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中, 所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积,那么我们称它为
2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中,
福大大架构师每日一题
2022/10/23
4460
2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中, 所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积,那么我们称它为
2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中,所有元素的乘积可以表示为一个或多个 互不相同的
2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中,
福大大架构师每日一题
2022/11/06
5190
2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中,所有元素的乘积可以表示为一个或多个 互不相同的
2022-06-23:给定一个非负数组,任意选择数字,使累加和最大且为7的倍数,返回最大累加和。 n比较大,10的5次方。 来自美团。3.26笔试。
2022-06-23:给定一个非负数组,任意选择数字,使累加和最大且为7的倍数,返回最大累加和。
福大大架构师每日一题
2022/06/23
2990
2022-06-23:给定一个非负数组,任意选择数字,使累加和最大且为7的倍数,返回最大累加和。 n比较大,10的5次方。 来自美团。3.26笔试。
2022-07-11:给定n位长的数字字符串和正数k,求该子符串能被k整除的子串个数。
2022-07-11:给定n位长的数字字符串和正数k,求该子符串能被k整除的子串个数。
福大大架构师每日一题
2022/07/11
5240
2022-07-11:给定n位长的数字字符串和正数k,求该子符串能被k整除的子串个数。
2023-03-20:给定一个无向图,保证所有节点连成一棵树,没有环, 给定一个正数n为节点数,所以节点编号为0~n-1,那么就一定有n-1条边, 每条边形式为
为了解决此问题,我们可以使用搜索和动态规划技术进行优化,下面将详细介绍两种算法的实现方法。
福大大架构师每日一题
2023/03/20
6830
2023-03-20:给定一个无向图,保证所有节点连成一棵树,没有环, 给定一个正数n为节点数,所以节点编号为0~n-1,那么就一定有n-1条边, 每条边形式为
2023-05-05:给定一个无向、连通的树 树中有 n 个标记为 0...n-1 的节点以及 n-1 条边 。 给定整数 n 和数组 edges , edge
输入: n = 6, edges = [0,1,0,2,2,3,2,4,2,5]。
福大大架构师每日一题
2023/05/05
2630
2023-05-05:给定一个无向、连通的树 树中有 n 个标记为 0...n-1 的节点以及 n-1 条边 。 给定整数 n 和数组 edges , edge
2022-12-22:给定一个数字n,代表数组的长度, 给定一个数字m,代表数组每个位置都可以在1~m之间选择数字, 所有长度为n的数组中,最长递增子序列长度为
2022-12-22:给定一个数字n,代表数组的长度,给定一个数字m,代表数组每个位置都可以在1~m之间选择数字,所有长度为n的数组中,最长递增子序列长度为3的数组,叫做达标数组。返回达标数组的数量。1 <= n <= 500,1 <= m <= 10,500 10 10 * 10,结果对998244353取模,实现的时候没有取模的逻辑,因为非重点。来自微众银行。答案2022-12-22:参考最长递增子序列。代码用rust编写。代码如下:use std::iter::repeat;fn main() {
福大大架构师每日一题
2022/12/22
2.3K0
2022-12-22:给定一个数字n,代表数组的长度, 给定一个数字m,代表数组每个位置都可以在1~m之间选择数字, 所有长度为n的数组中,最长递增子序列长度为
2022-06-09:每个会议给定开始和结束时间, 后面的会议如果跟前面的会议有任何冲突,完全取消冲突的、之前的会议,安排当前的。 给定一个会议数组,返回安排的
2022-06-09:每个会议给定开始和结束时间,后面的会议如果跟前面的会议有任何冲突,完全取消冲突的、之前的会议,安排当前的。给定一个会议数组,返回安排的会议列表。来自通维数码。答案2022-06-09:彻底的流程模拟。线段树。代码用rust编写。代码如下:use rand::Rng;fn main() { let n: i32 = 100; let t: i32 = 5000; let test_time: i32 = 20000; println!("测试开始"); fo
福大大架构师每日一题
2022/06/09
4390
2022-06-09:每个会议给定开始和结束时间, 后面的会议如果跟前面的会议有任何冲突,完全取消冲突的、之前的会议,安排当前的。 给定一个会议数组,返回安排的
2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7。施展魔法之后,A和B通过该边到达
点的数量 <= 10^5,边的数量 <= 2 * 10^5,1 <= 边的权值 <= 10^6。
福大大架构师每日一题
2022/07/31
7710
2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7。施展魔法之后,A和B通过该边到达
2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器, 每台机器都有一个能量水平,分别为a1、a2、…、an, 小美每次操作可以选其中的一台机器
第二行为n个正整数a1, a2,...... an,其中ai表示第i台机器初始的能量水平。
福大大架构师每日一题
2023/01/02
3080
2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器, 每台机器都有一个能量水平,分别为a1、a2、…、an, 小美每次操作可以选其中的一台机器
2023-03-06:给定一个二维网格 grid ,其中: ‘.‘ 代表一个空房间 ‘#‘ 代表一堵 ‘@‘ 是起点 小写字母代表钥匙 大写字母代表锁 我们从起
2023-03-06:给定一个二维网格 grid ,其中:'.' 代表一个空房间'#' 代表一堵'@' 是起点小写字母代表钥匙大写字母代表锁我们从起点开始出发,一次移动是指向四个基本方向之一行走一个单位空间我们不能在网格外面行走,也无法穿过一堵墙如果途经一个钥匙,我们就把它捡起来。除非我们手里有对应的钥匙,否则无法通过锁。假设 k 为 钥匙/锁 的个数,且满足 1 <= k <= 6,字母表中的前 k 个字母在网格中都有自己对应的一个小写和一个大写字母换言之,每个锁有唯一对应的钥匙,每个钥匙也有唯一对应的锁
福大大架构师每日一题
2023/03/06
3930
2023-03-06:给定一个二维网格 grid ,其中: ‘.‘ 代表一个空房间 ‘#‘ 代表一堵 ‘@‘ 是起点 小写字母代表钥匙 大写字母代表锁 我们从起
2022-06-20:一个二维矩阵,上面只有 0 和 1,只能上下左右移动, 如果移动前后的元素值相同,则耗费 1 ,否则耗费 2。 问从左上到右下的最小耗费。
1.网上非常流行的方法,但这是错误的。这道题动态规划是做不了的。因为上下左右四个方向都可能走,而不是右下两个方向。
福大大架构师每日一题
2022/06/20
7070
2022-06-20:一个二维矩阵,上面只有 0 和 1,只能上下左右移动, 如果移动前后的元素值相同,则耗费 1 ,否则耗费 2。 问从左上到右下的最小耗费。
2022-06-29:x = { a, b, c, d },y = { e, f, g, h },x、y两个小数组长度都是4。如
[左神java代码](https://github.com/algorithmzuo/weekly-problems/blob/main/src/class_2022_04_2_week/Code06_PerfectPairNumber.java)
福大大架构师每日一题
2023/06/08
2560
2022-06-29:x = { a, b, c, d },y = { e, f, g, h },x、y两个小数组长度都是4。如
推荐阅读
2022-06-25:给定一个正数n, 表示有0~n-1号任务, 给定一个长度为n的数组time,time[i]表示i号任务做完的时间, 给定一个二维数组mat
3910
2022-06-06:大妈一开始手上有x个鸡蛋,她想让手上的鸡蛋数量变成y, 操作1 : 从仓库里拿出1个鸡蛋到手上,x变成x+1个
1750
2022-09-27:给定一个棵树, 树上每个节点都有自己的值,记录在数组nums里, 比如nums[4] = 10,表示4号点的值是10, 给定树上的每一条边
5160
2022-11-04:给定一个正数n,表示有多少个节点 给定一个二维数组edges,表示所有无向边 edges[i] = {a, b} 表示a到b有一条无向边
4580
2023-09-03:用go编写。给你一个 n 个节点的无向无根树,节点编号从 0 到 n - 1 给你整数 n 和一个长度为
2220
2022-09-05:作为国王的统治者,你有一支巫师军队听你指挥。 :给你一个下标从 0 开始的整数数组 strength , 其中 strength[i] 表
2150
2023-03-20:给定一个无向图,保证所有节点连成一棵树,没有环,给定一个正数n为节点数,所以节点编号为0~n-1,那么就一
2920
2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中, 所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积,那么我们称它为
4460
2022-10-23:给你一个整数数组 nums 。如果 nums 的一个子集中,所有元素的乘积可以表示为一个或多个 互不相同的
5190
2022-06-23:给定一个非负数组,任意选择数字,使累加和最大且为7的倍数,返回最大累加和。 n比较大,10的5次方。 来自美团。3.26笔试。
2990
2022-07-11:给定n位长的数字字符串和正数k,求该子符串能被k整除的子串个数。
5240
2023-03-20:给定一个无向图,保证所有节点连成一棵树,没有环, 给定一个正数n为节点数,所以节点编号为0~n-1,那么就一定有n-1条边, 每条边形式为
6830
2023-05-05:给定一个无向、连通的树 树中有 n 个标记为 0...n-1 的节点以及 n-1 条边 。 给定整数 n 和数组 edges , edge
2630
2022-12-22:给定一个数字n,代表数组的长度, 给定一个数字m,代表数组每个位置都可以在1~m之间选择数字, 所有长度为n的数组中,最长递增子序列长度为
2.3K0
2022-06-09:每个会议给定开始和结束时间, 后面的会议如果跟前面的会议有任何冲突,完全取消冲突的、之前的会议,安排当前的。 给定一个会议数组,返回安排的
4390
2022-07-31:给出一个有n个点,m条有向边的图, 你可以施展魔法,把有向边,变成无向边, 比如A到B的有向边,权重为7。施展魔法之后,A和B通过该边到达
7710
2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器, 每台机器都有一个能量水平,分别为a1、a2、…、an, 小美每次操作可以选其中的一台机器
3080
2023-03-06:给定一个二维网格 grid ,其中: ‘.‘ 代表一个空房间 ‘#‘ 代表一堵 ‘@‘ 是起点 小写字母代表钥匙 大写字母代表锁 我们从起
3930
2022-06-20:一个二维矩阵,上面只有 0 和 1,只能上下左右移动, 如果移动前后的元素值相同,则耗费 1 ,否则耗费 2。 问从左上到右下的最小耗费。
7070
2022-06-29:x = { a, b, c, d },y = { e, f, g, h },x、y两个小数组长度都是4。如
2560
相关推荐
2022-06-25:给定一个正数n, 表示有0~n-1号任务, 给定一个长度为n的数组time,time[i]表示i号任务做完的时间, 给定一个二维数组mat
更多 >
LV.9
北京动视元科技有限公司研发工程师
目录
  • 整个类的设计如下:
  • 单链表的结构
  • 链表存储的结点
  • 链表的基本操作
    • 链表结点的增加
    • 链表结点的删除
    • 虚拟头结点删除链表元素的实现
    • 使用虚拟头结点进行链表的插入
  • 查找某个元素是否在链表的结点上
  • 完整的代码实现:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档