又是做噩梦早醒了,似乎已经习惯了,所以反而觉得没有那么失落了,慢慢也开始习惯了每天刷题,对着一道题卡住,然后最终解决,再总结为什么卡在那里。虽然还是会焦虑,但是没有之前那么焦虑了,保持目前的状态,静下心来积累知识,链表练习了三天了,今天明显比前两天熟练了,而且也可以脱离官方答案自己想出方法修bug了,反复练习是有用的,哪怕刚开始只是把官方答案复写一遍,坚持练习也是有用的。
今日进度:坚持刷题,虽然链表刷得很艰难,但是有在提高,是有用的坚持录小王子,其实已经中断两天了坚持锻炼坚持记录,刷完题不认真总结相当于没有刷
学习笔记:在Java中,类的多重继承是不合法,但接口允许多重继承。在接口的多重继承中extends关键字只需要使用一次,在其后跟着继承接口。如下所示:
输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]
解题思路:先遍历一遍到链表的长度,再遍历一遍到n-k个节点;两个指针p,q使p在虚拟头节点,q移动n+1次,两个指针同步移动,直到q到达链表尾部
/**
* 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) {
ListNode dn = new ListNode(0,head);
ListNode slow = dn;
ListNode fast = dn;
for(int i=0; i旋转链表给你一个链表的头节点head,旋转链表,将链表每个节点向右移动k个位置。
输入:head=[1,2,3,4,5],k=2输出:[4,5,1,2,3]
解题思路:相当于数组需要向右移动kmodn次,可以设置两个指针,fast指针比slow多移动move个节点,在一起移动两个节点,知道fast到尾部,slow指向的下一个节点就是新的头节点的位置,将slow的next设为空,fast指向head,返回新的头节点即可。
/**
* 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 rotateRight(ListNode head, int k) {
if(head==null || head.next==null || k==0){
return head;
}
int n = 0;
ListNode dn = new ListNode(0,head);
ListNode slow = dn;
ListNode fast = dn;
ListNode lent = dn;
while(lent.next!=null){
n++;
lent = lent.next;
}
int move = k % n;
if(move == 0){
return head;
}
for(int i=0; i重排链表给定一个单链表L的头节点head,单链表L表示为:
L0→L1→…→Ln-1→Ln
请将其重新排列后变为:
L0→Ln→L1→Ln-1→L2→Ln-2→…
输入:head=[1,2,3,4]输出:[1,4,2,3]提示:链表的长度范围为[1,5*10^4]1<=nodval<=1000
解题思路:先通过快慢指针找到链表的中点,将右边部分的链表反转,在将两个链表依次按顺序合并起来。实现的时候可能会遇到划分中点的问题,无论是奇数还是偶数链表,slow指针的下一个节点始终是右边链表头节点,在合并链表的时候,左边的节点下一个指向右边,右边的下一个又指向左边,如果左边的链表为空时,应该不修改下一个右边链表节点的指向。
/**
* 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 void reorderList(ListNode head) {
if(head.next==null){
return;
}
ListNode dn = new ListNode(0,head);
ListNode slow = dn;
ListNode fast = dn;
while(fast.next!=null && fast.next.next!=null){
slow = slow.next;
fast = fast.next.next;
}
ListNode nh = slow.next;
slow.next = null;
nh = reverse(nh);
merge(head,nh);
}
public ListNode reverse(ListNode nh){
ListNode pre = null;
while(nh != null){
ListNode next = nh.next;
nh.next = pre;
pre = nh;
nh = next;
}
return pre;
}
public void merge(ListNode head, ListNode nh){
ListNode tmp1;
ListNode tmp2;
while(head!=null && nh!=null){
tmp1 = head.next;
tmp2 = nh.next;
head.next = nh;
head = tmp1;
if(head!=null){
nh.next = head;
nh = tmp2;
}
}
}
}
删除链表中的节点请编写一个函数,用于删除单链表中某个特定节点。在设计函数时需要注意,你无法访问链表的头节点head,只能直接访问要被删除的节点。题目数据保证需要删除的节点不是末尾节点。
输入:head=[4,5,1,9],node=5输出:[4,1,9]解释:指定链表中值为5的第二个节点,那么在调用了你的函数之后,该链表应变为4->1->9
解题思路:将当前节点的下一个节点值复制给当前节点,再将当前节点删除,如果当前节点为最后一个,则直接令当前节点等于null。
差点漏了一道简单的题,还好很快就补上了,今天刷题太入迷,有点晚了,明天再运动和录小王子,又是周末了,下午久违地准备去看演出,还挺难得的,明日继续更新。
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点