刷题日记 Day4
本篇文章 , 是在代码随想录 60 天编程挑战的基础上进行的题目讲解
参与链接在此 : https://programmercarl.com/other/xunlianying.html
大家好 , 这个专栏 , 给大家带来的是 60 天刷题强训 . 最令大家头疼的事就是刷题了 , 题目又臭又长又抽象 , 有的题读都读不懂 , 更别说做了 . 所以 , 这个专栏想要帮助大家摆脱困境 , 横扫饥饿 , 做回自己 . 让大家掌握最常见的面试题 , 面对陌生的题目也不至于无从下手 .
也希望大家监督 , 60 天从 0 到 1 , 咱们一起做大佬 ~
今天是 Day4 , 大家加油~
专栏链接 : https://blog.csdn.net/m0_53117341/category_12247938.html?spm=1001.2014.3001.5482
昨天的打卡链接 : http://t.csdn.cn/zNysy
一 . Leetcode 24 . 两两交换链表中的节点
题目链接 : 24. 两两交换链表中的节点
其实对于链表的很多问题 , 不是那么麻烦 .
但是必须大家对这道题有清晰的思路 , 才能完美实现
那么给大家介绍一下这道题的思路
如果理顺了思路 , 代码一点都不难实现
代码给大家贴在这里了
/**
* Definition for singly-linked list.
* 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; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
// 1. 定义虚拟头节点
ListNode tmpHead = new ListNode(-1);
tmpHead.next = head;
// 2. 定义 cur 指针,让他先指向虚拟头结点
ListNode cur = tmpHead;
// 3. 循环交换链表节点
while(cur.next != null && cur.next.next != null) {
// 先将这组第一个节点保存起来,要不然后面找不到
ListNode tmp1 = cur.next;
// 再将下一组链表的第一个节点保存起来,省的也找不到
ListNode tmp2 = cur.next.next.next;
// 进行交换
cur.next = cur.next.next;
cur.next.next = tmp1;
tmp1.next = tmp2;
// 要将 cur 移动到这组最后一个元素
cur = cur.next.next;
}
return tmpHead.next;
}
}
二 . Leetcode 19 . 删除链表的倒数第 N 个节点
题目链接 : 19. 删除链表的倒数第 N 个结点
这道题 , 还是清楚了思路之后不难实现
我们就给大家介绍一下这道题的思路
/**
* Definition for singly-linked list.
* 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; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// 1. 定义虚拟头节点
ListNode tmpHead = new ListNode(-1);
tmpHead.next = head;
// 2. 定义快慢指针
ListNode fast = tmpHead;
ListNode slow = tmpHead;
// 3. 先让 fast 走 n+1 步
int tmp = n + 1;
// 注意判断 fast 指针走没走到空
// 比如:1 2 3 4 5 , 找倒数第 100 个节点,fast 走到 100 肯定是空指针了
while(tmp-- != 0 && fast != null) {
fast = fast.next;
}
// 4. 接下来 fast slow 一起走
// fast 走到空的时候,slow就到了倒数第 k 个节点的前面
while(fast != null) {
fast = fast.next;
slow = slow.next;
}
// 5. 跳过倒数第 k 个节点
slow.next = slow.next.next;
return tmpHead.next;
}
}
三 . 面试题 02.07. 链表相交
题目链接 : 面试题 02.07. 链表相交
这道题 , 也是标准的知道解法 , 题目就非常 easy 的一道题
大家来看一下解法~
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 1. 定义两条指针,分别指向 headA,headB
ListNode cur1 = headA;
ListNode cur2 = headB;
// 2. 让 cur1 cur2 一直往后走
while(cur1 != cur2) {
// 当 cur1 走到空的时候,让他指向 headB
if(cur1 == null) {
cur1 = headB;
} else {
// 否则正常往后走就行
cur1 = cur1.next;
}
// 当 cur2 走到空的时候,让他指向 headA
if(cur2 == null) {
cur2 = headA;
} else {
// 否则正常往后移动
cur2 = cur2.next;
}
}
// 3. 这时候,cur1 cur2 相遇,返回其中任意一个即可
return cur1;
}
}
四 . Leetcode 142 . 环形链表 II
题目链接 : 142. 环形链表 II
实际上这道题 , 是两道题
它的前身是判断链表是否有环 141. 环形链表
那我们就这两道题都看了
我们这里只实现环形链表 II 这道题 , 因为这道题会了 , 那环形链表 I 也没问题~
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
// 1. 定义快慢指针
ListNode fast = head;
ListNode slow = head;
// 2. 让快慢指针移动,相遇就代表链表有环
// 循环条件:因为 fast 一直走在 slow 前面,所以只需要判断 fast 的条件即可
while(fast != null && fast.next != null) {
// 快指针每次走两步,慢指针每次走一步
fast = fast.next.next;
slow = slow.next;
// 相遇的时候,在相遇点处创建一个 index1 指针,在起点创建一个 index2 指针
// 相遇的时候就是入口节点
if(fast == slow) {
ListNode index1 = fast;
ListNode index2 = head;
// index1 index2 各自移动
while(index1 != index2) {
index1 = index1.next;
index2 = index2.next;
}
// 这时候,index1 index2 相遇了,返回其中一个即可
return index1;
}
}
// 整个 while 循环走完了还没找到 -> 返回 null
return null;
}
}
今天的任务就完成啦~
没白活一天~
如果对你有帮助的话 , 请一键三连嗷~