这是我觉得非常巧妙的一个快慢指针解法,自认为我讲得也非常清楚,可以直接点目录跳到逐句代码讲解看
题目
- 给单链表加一
自己没想出来哈哈哈哈(尴尬😅,因为我居然没看懂那个简单链表的定义
————————————————————
先讲一下这个链表的节点类吧
高手直接跳过,像我这种刚起步刷题的可以看看
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
相当于定义一个ListNode类,其中成员变量包括int类型的value储存一个值(这里写的val),和一个ListNode类型的next,然后提供了一个有参数构造函数,用来新建一个节点类,可以想象成用完构造函数会这个样子
那这也不像是链啊,没事,再建一个ListNode1,让ListNode.next = ListNode1即可。
想象一下,多创建几个ListNode用next一个一个赋值不就是一个链子了。题中的 [1,2,3]应该是创建三个节点一个个连起来。
ListNode l1 = new ListNode(1);
ListNode l2 = new ListNode(2);
ListNode l3 = new ListNode(3);
l1.next = l2;
l2.next = l3;
return l1;
类似代码就是这样的。
好了开始讲思路
这是我在题解里看到的一个很巧妙的题解,采用的是 快慢指针 。
这不还是双指针???
没系统学完数据结构算法还不太懂,以后回来补坑
思路:
- 用快指针fast,遍历链表 fast.val != 9,慢指针移动到当前快指针处
- fast.val = 9,慢指针原地不动
- 遍历结束,慢指针的值加一,慢指针后续所有节点值设置为0,打完收工!
这道题用快慢指针的原因是,需要考虑进位问题,要是不考虑进位问题,那直接找到最后一个节点,不就是个位,加一就完事了。我们需要一个指针去遍历链表;有多个位置需要进位的情况只能是从个位开始往前有连续的9,我们需要找到那个不为9的第一个,自己加1,然后把后面的都变成0,就相当于从个位把进位传过来了
⬆️说得挺乱,我自己能看懂就行030
逐句注释的代码在这
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode plusOne(ListNode head) {
//这个方法传入的是一个链表head,说是链表,其实是一个节点,这个节点后面跟着一堆next的节点,所以也可以叫这个链表的头节点,命名成head;
//下面分别定义了一个指向头节点的快指针
//一个指向头节点之前一个新建节点的慢指针,慢指针的值被初始化为0
ListNode fastPoint = head;
ListNode slowPoint = new ListNode(0);
slowPoint.next = head;
//while语句控制快指针从头遍历到结尾
while (null != fastPoint){
//如果快指针在的节点不等于9,那就让慢指针也过来站在一起,然后快指针继续往后走
if (fastPoint.val != 9) {
slowPoint = fastPoint;
}
fastPoint = fastPoint.next;
//最终慢指针停在的位置就是快指针找到的9的前面一个节点
// 比如 4 3 9 9
// 一开始会被初始化为 0 4 3 9 9 慢指针在0上,快指针在4上
// ⬆️ ⛰️
//然后 快指针继续往后到3,发现不是9,就叫慢指针过来站在一起
// 0 4 3 9 9
// ⬆️⛰️
//然后快指针继续往后走,发现没有不等于9的地方了,就再也没叫慢指针过来了
// 0 4 3 9 9
// ⬆️ ⛰️
//那最后我们发现,慢指针后面全是9,加1的话就是慢指针自己的地方加1,然后后面全变0,就是下面的代码实现的
}
slowPoint.val++;
ListNode curr = slowPoint.next;
while (null != curr) {
curr.val=0;
curr = curr.next;
}
//这里的return比较拽,判断慢指针是不是还在头指针前面没动,
//要是最后这种
// 0 9 9 9 9
// ⬆️ ⛰️
//那就返回新的,因为会变成
// 1 0 0 0 0
// ⬆️ ⛰️
//不然就返回原来的
return slowPoint.next == head ? slowPoint : head;
}
}
讲完啦,我感觉我是人上人了