LeetCode 链表题 ( Java )
leetcode 237. 删除链表中的节点
链接:https://leetcode-cn.com/problems/delete-node-in-a-linked-list/
示例 :
输入: head = [4,5,1,9], node = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
这道题比较简单,修改之前节点的 next
指针,使其指向之后的节点:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
leetcode 160. 相交链表
链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。要求返回 c1 这个节点。
先得到两条链表的长度差 offset,再将长链表跳过 offset 个节点,然后再让这两个链表轮流逐个遍历节点,直到相遇。
比如上图 A 和 B 差一个长度差为 1,先跳过 b1 这个结点到达 b2,然后 A 开始从 a1 遍历,到达 a2, B 到达 b3; 随后 A 到达 c1,B 到达 c1,两点相遇,返回 c1.
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null)
return null; int lengthA = getListLength(headA);
int lengthB = getListLength(headB);
ListNode longList = headA;
ListNode shortList = headB;
int offset = Math.abs(lengthA - lengthB);
if(lengthA < lengthB){
longList = headB;
shortList = headA;
}
for(int i=0; i < offset; i++){
longList = longList.next;
}
while(shortList != longList){
shortList = shortList.next;
longList = longList.next;
}
return shortList;
}
public int getListLength(ListNode p){
int length = 0;
while(p != null){
length++;
p = p.next;
}
return length;
}
}
我又看了这道题的题解,看到有其他解法:两条链表先遍历一轮(消除长度差),当链表到达结尾的时候,反而让到达链表末尾的节点指向另一个链表的头部,然后再接着遍历,这样就消除了两条链表的长度差,可以大致理解为:两个人以同样的速度跑步,跑的路程也一致,那么肯定会同一个时间点到达终点。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode pA = headA, pB = headB;
while (pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
leetcode 206. 反转链表
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
此题的思路是逐个反转,先变成 NULL<-1 2->3->4->5->NULL; 然后是 1<-2 3->4->5->NULL; 接着是 1<-2<-3 4->5->NULL,以此类推。那么我们首先就要先创建一个空节点为 prev,使得 1 指向它,但是,需要先把 2 这个节点保存起来,不然当 1 指向 NULL 后就失去了 2 以后的数据。完成第一次反转后就一直迭代下去。可能表达得不太行,看代码吧:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
while(head != null) {
ListNode next = head.next;
head.next = prev; // 翻转 prev = head;
head = next;
}
return prev;
}
}
如果文字解释看不懂,代码也看不懂,那就视频吧,推荐这个小姐姐讲的 用Java解决翻转链表 Leetcode206 Reverse Linked List
leetcode 141. 环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
(1) 哈希
遇到这种类型得题目一般大部分都是用 hash ,通过遍历把每个节点存起来,如果该节点后续还被访问到,则表示该链表为环形链表。
public boolean hasCycle(ListNode head) {
Set<ListNode> nodes = new HashSet<>();
while (head != null) {
if (nodes.contains(head)) {
return true;
} else {
nodes.add(head);
}
head = head.next;
}
return false;
}
(2)双指针
定义两个指针,从 head 开始,慢指针移动一步,快指针移动两步,如果两个指针相遇则为环形链表,否则不是。这个道理就跟两个不同速度的人在同一条跑道上跑步一样,如果是环形的总会相遇。
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null)
return false;
ListNode slow = head;
ListNode fast = head.next;
while(fast != null && fast.next != null) {
if (slow == fast){
return true;
}
slow = slow.next;
fast = fast.next.next;
}
return false;
}
leetcode 19. 删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
(1)第一种方法:由于不清楚链表的长度,因此可以先遍历链表得到其长度,然后第二次遍历将倒数第N个节点删除,即被删除节点的前一个节点指向删除节点的后一个节点:
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
int length = 0;
ListNode list = head;
while (list != null) {
length++;
list = list.next;
}
length -= n;
list = dummy;
while (length > 0) {
length--;
list = list.next;
}
list.next = list.next.next;
return dummy.next;
}
(2)第二种方法:使用双指针,先让其中一个指针走 N+1 步,然后两个指针同时移动,到达被删除节点的前一个节点时把它删除:
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode p = dummy;
ListNode q = dummy;
for (int i = 0; i <= n; i++) {
q = q.next;
}
while (q != null) {
p = p.next;
q = q.next;
}
p.next = p.next.next;
return dummy.next;
}
leetcode 21. 合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode node = new ListNode(0);
ListNode pre = node;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
pre.next = l1;
l1 = l1.next;
}
else{
pre.next = l2;
l2 = l2.next;
}
pre = pre.next;
}
pre.next = l1 == null? l2:l1;
return node.next;
}
}
LeetCode 链表题 ( Java )的更多相关文章
- 【LeetCode刷题Java版】Reverse Words in a String
Given an input string, reverse the string word by word. For example, Given s = "the sky is blue ...
- LeetCode算法题-Design LinkedList(Java实现)
这是悦乐书的第300次更新,第319篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第168题(顺位题号是707).设计链表的实现.您可以选择使用单链表或双链表.单链表中的 ...
- LeetCode算法题-Design HashMap(Java实现)
这是悦乐书的第299次更新,第318篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第167题(顺位题号是706).在不使用任何内置哈希表库的情况下设计HashMap.具体 ...
- LeetCode算法题-Delete Node in a Linked List(Java实现)
这是悦乐书的第197次更新,第204篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第60题(顺位题号是235).编写一个函数来删除单链表中的节点(尾部除外),只允许访问该 ...
- LeetCode算法题-Palindrome Linked List(Java实现)
这是悦乐书的第196次更新,第202篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第58题(顺位题号是234).给出一个单链表,确定它是否是回文.例如: 输入:1-> ...
- LeetCode算法题-Reverse Linked List(Java实现)
这是悦乐书的第192次更新,第195篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第51题(顺位题号是206).反转单链表.例如: 输入:1-> 2-> 3- ...
- LeetCode算法题-Remove Linked List Elements(Java实现)
这是悦乐书的第189次更新,第191篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第48题(顺位题号是203).移除单链表中节点值为val的节点.例如: 输入:1-> ...
- LeetCode算法题-Happy Number(Java实现)
这是悦乐书的第188次更新,第190篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第47题(顺位题号是202).编写算法以确定数字是否"幸福". 幸福 ...
- LeetCode算法题-Intersection of Two Linked Lists(Java实现)
这是悦乐书的第178次更新,第180篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第37题(顺位题号是160).编写程序以找到两个单链表交叉的节点.例如: 以下两个链表: ...
随机推荐
- 全栈项目|小书架|服务器开发-Koa2 全局异常处理
什么是异常 做开发的基本都知道异常,像Android开发中常见的ANR异常.空指针异常,服务器开发中经常遇到的异常404,500异常,还有一些其他常见的异常,具体可见HTTP状态码. 基本上这些异常可 ...
- 7.30 NOIP模拟10
T1.辣鸡 考试的时候竟然被我以“麻烦”弃掉了,赛后发现这题好水啊,直接sort一下寻找四周即可. T2.模板 考试时期望得分70,实际得分5 首先看到这种题基本就是线段树,我们以时间为下标,对每一个 ...
- csps模拟测试70
又炸了,T1没开$long long$,炸掉$50pts$,昨天因为SB错误挂掉$100pts$. 我kuku了,以后细心点吧.
- python学习之【第二篇】:Python中的数字及其所具有的方法
1.前言 Python 数字(number)数据类型用于存储数值.数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间. 2.创建数字对象 以下实例在变量赋值时 Number ...
- Net Core Identity 身份验证:注册、登录和注销 (简单示例)
一.前言 一般我们自己的系统都会用自己设置的一套身份验证授权的代码,这次用net core的identity来完成简单的注册.登录和注销. 二.数据库 首先就是创建上下文,我这里简单的建了Users和 ...
- .net core Json字符串的序列化和反序列化通用类源码,并模拟了10万数据对比DataContractJsonSerializer和Newtonsoft性能
我们在开发中Json传输数据日益普遍,有很多关于Json字符串的序列化和反序列化的文章大多都告诉你怎么用,但是却不会告诉你用什么更高效.因为有太多选择,人们往往会陷入选择难题. 相比.NET Fram ...
- python手册学习笔记1
笔记1 > http://www.pythondoc.com/pythontutorial3/controlflow.html 参数传递 Python中sys.argv的用法 调用解释器时,脚本 ...
- Kickstart Round H 2019 Problem B. Diagonal Puzzle
有史以来打得最差的一次kickstart竟然发生在winter camp出结果前的最后一次ks = = 感觉自己的winter camp要凉了 究其原因,无非自己太眼高手低,好好做B, C的小数据,也 ...
- vue-create 报错 command failed: yarn --registry=https://registry.npm.taobao.org --disturl=https://npm.taobao.org/dist 完美解决方案
@vue/cli 3.x 创建项目失败解决方案 报错信息 command failed: yarn --registry=https://registry.npm.taobao.org --distu ...
- 基于@Scheduled注解的Spring定时任务
1.创建spring-task.xml 在xml文件中加入命名空间 <beans xmlns="http://www.springframework.org/schema/beans& ...