携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情 >>
每日三刷,剑指千题
计划简介:
- 每日三题,以中等题为主,简单题为辅进行搭配。保证质量题1道,数量题3道。
- 每日早通勤在LeetCode手机端选题,思考思路,没答案的直接看题解。
- 每日中午进行编码,时间控制在一小时之内。
- 下班前半小时进行整理总结,并发布到掘金每日更文活动。
说明:
- 基于以前的刷题基础,本次计划以中等题为主,大部分中等题都可以拆分为多个简单题,所以数量保证3,质量保证一道中等题即可。
- 刷题顺序按照先刷链表、二叉树、栈、堆、队列等基本数据结构,再刷递归、二分法、排序、双指针等基础算法,最后是动态规划、贪心、回溯、搜索等复杂算法。
- 刷题过程中整理相似题型,刷题模板。
- 目前进度 120/1000 。
[1019]链表中的下一个更大节点
给定一个长度为 n 的链表 head
对于列表中的每个节点,查找下一个 更大节点 的值。也就是说,对于每个节点,找到它旁边的第一个节点的值,这个节点的值 严格大于 它的值。
返回一个整数数组 answer ,其中 answer[i] 是第 i 个节点( 从1开始 )的下一个更大的节点的值。如果第 i 个节点没有下一个更大的节点,设置 answer[i] = 0 。
示例 1:
输入:head = [2,1,5]
输出:[5,5,0]
解析
如果是数组的话,双重循环肯定是搞定了,不管快慢,链表就需要考虑指针了。快慢指针 or 滑动窗口?
用双指针写了一版,效率不高,但是能过。
看了一下解析里有用单调栈的,有点类似之前的接雨水了,等到栈的专题是再研究。
经过这么多天的研究,链表涉及最多的就是双指针,因为这狗东西天然就带指针。再有就是递归和迭代。还是比较简单的。
明天会再做几道环形链表,这部分内容就可以告一段落了,开始二叉树。
Code
class Solution {
public int[] nextLargerNodes(ListNode head) {
int size = 0;
ListNode start = head;
while (head != null) {
size++;
head = head.next;
}
if (size == 1) {
return new int[]{0};
}
int[] ans = new int[size];
for (int i = 0; i < size - 1; i++) {
ListNode index = start.next;
while (index != null && start.val >= index.val) {
index = index.next;
}
if (index == null) {
ans[i] = 0;
} else {
ans[i] = index.val;
}
start = start.next;
}
return ans;
}
}
[328]奇偶链表
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。
你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。
示例 1:
输入: head = [1,2,3,4,5]
输出: [1,3,5,2,4]
解析
有点像分割链表,先把奇数位的拼在一个链表后面,偶数位的拼在一个链表后面,最后把这两个链表拼在一起,看下能不能过。
哈哈哈,过了!
Code
class Solution {
public ListNode oddEvenList(ListNode head) {
ListNode ji = new ListNode(0);
ListNode ou = new ListNode(0);
ListNode ouHead = ou;
ListNode jiHead = ji;
int flag = 1;
while (head!=null){
ListNode temp = head;
head = head.next;
if (flag==1){
ji.next = temp;
ji = ji.next;
flag = 0;
}else {
ou.next = temp;
ou = ou.next;
flag = 1;
}
temp.next = null;
}
ji.next = ouHead.next;
return jiHead.next;
}
}
[面试题 02.03]删除中间节点
若链表中的某个节点,既不是链表头节点,也不是链表尾节点,则称其为该链表的「中间节点」。
假定已知链表的某一个中间节点,请实现一种算法,将该节点从链表中删除。
例如,传入节点 c(位于单向链表 a->b->c->d->e->f 中),将其删除后,剩余链表为 a->b->d->e->f
示例:
输入:节点 5 (位于单向链表 4->5->1->9 中)
输出:不返回任何数据,从链表中删除传入的节点 5,使链表变为 4->1->9
解析
还是删除节点的套路,水题而已。
Code
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
\