携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情 >>
每日三刷,剑指千题
计划简介:
- 每日三题,以中等题为主,简单题为辅进行搭配。保证质量题1道,数量题3道。
- 每日早通勤在LeetCode手机端选题,思考思路,没答案的直接看题解。
- 每日中午进行编码,时间控制在一小时之内。
- 下班前半小时进行整理总结,并发布到掘金每日更文活动。
说明:
- 基于以前的刷题基础,本次计划以中等题为主,大部分中等题都可以拆分为多个简单题,所以数量保证3,质量保证一道中等题即可。
- 刷题顺序按照先刷链表、二叉树、栈、堆、队列等基本数据结构,再刷递归、二分法、排序、双指针等基础算法,最后是动态规划、贪心、回溯、搜索等复杂算法。
- 刷题过程中整理相似题型,刷题模板。
- 目前进度 114/1000 。
[82] 删除排序链表中的重复元素 II
给定一个已排序的链表的头 head
, 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]
解析
四指针是为了夺人眼球,其核心思想依然是双指针,滑动窗口,只不过为了删除操作,需要维护前一个结点。
注意如果是[1,2,3,3,3] 这种 3 是删不掉的,所以循环完判断一下是否还有未删除的,再做一次删除。
Code
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null) return null;
ListNode dummy = new ListNode(-1000,head);
ListNode prev = dummy;
ListNode delEnd = null;
ListNode delStart= new ListNode(-100,dummy);
while (head!=null){
if (head.val==prev.val){
// 窗口有边界后移
delEnd = head;
}else {
if (delEnd!=null){
// 删除
delStart.next = delEnd.next;
prev = delStart.next;
// 这里一定要置null,最后才能判断是否有没删除的
delEnd = null;
}else {
prev = prev.next;
// 窗口左边界前移
delStart = delStart.next;
}
}
head = head.next;
}
if (delEnd != null){
delStart.next = null;
}
return dummy.next;
}
}
[86]分隔链表
给你一个链表的头节点 head
和一个特定值 x
,请你对链表进行分隔,使得所有 小于 x
的节点都出现在 大于或等于 x
的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
示例 1:
输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
解析
迭代法,正常的去遍历,小于特定值的拼接在一个链表就后面,大于等于特定值的拼接在两一个链表后面。最后把两个链表拼在一起就行。空间利用率不高。
我觉得如果把链表换成数组,这道题就会是简单题了。
Code
class Solution {
public ListNode partition(ListNode head, int x) {
if (head==null)return null;
ListNode small = new ListNode(0);
ListNode big = new ListNode(0);
ListNode dummyBig = big;
ListNode dummySmall= small;
while (head != null) {
if (head.val < x){
small.next = head;
head = head.next;
small.next.next=null;
small = small.next;
} else {
big.next = head;
head = head.next;
big.next.next = null;
big = big.next;
}
}
small.next = dummyBig.next;
return dummySmall.next;
}
}
[剑指 Offer 25]合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
解析
做过的一道题,复习一下,类似的还有 合并两个有序数组。
Code
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode ans = new ListNode(0);
ListNode dummy = ans;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
ans.next = l1;
l1 = l1.next;
} else {
ans.next = l2;
l2 = l2.next;
}
ans = ans.next;
}
ans.next = l1 == null ? l2 : l1;
return dummy.next;
}
}
\