🔥博客主页: 小扳_-CSDN博客
❤感谢大家点赞👍收藏⭐评论✍

文章目录
为了更好的讲解算法的具体内容,先创建好链表,实现一个带哨兵的单链表。
代码如下:
import java.util.Iterator; public class List implements Iterable{ private Node hand; static class Node { public int value; public Node next; public Node() { } public Node(int value, Node next) { this.value = value; this.next = next; } } public List() { hand = new Node(0,null); } @Override public Iteratoriterator() { return new Iterator() { Node p = hand.next; @Override public boolean hasNext() { return p != null; } @Override public Integer next() { int value = p.value; p = p.next; return value; } }; } }之前的篇章都有讲解过以上的每一个方法及其作用,需要了解的点击一下链接:
介绍两种方式来实现该算法:
一、遍历链表来实现
二、使用递归来实现
实现思路为:设置两个节点分别为: o1, 一开始指向哨兵节点。o2,一开始指向头节点(也就是 哨兵节点指向的节点),想让 o2 节点往后走一步,来判断当前 o2 的节点的值是否为需要的节点,若是,则让 o1 指向 o2.next 节点,然后 o2 = o1.next 接着往后走;若不是,则让 o1 = o2 完成赋值(意味着 o1 永远跟着 o2 节点后面,o2 永远比 o1 走前一步),接着 o2 = o2.next 往后走。循环终止的条件为,当 o2 == null 就该停止了。
代码如下:
//根据值来删除节点 public void removeValue( List list, int value) { Node o1 = list.hand; Node o2 = list.hand.next; while (o2 != null) { if (o2.value == value) { o1.next = o2.next; o2 = o1.next; }else { o1 = o2; o2 = o2.next; } } }再讲个好理解的思路:把 o1 比作战场上的大部队,把 o2 比作地雷兵,每一次往前走的时候,都需要让地雷兵先去排雷,若前方没雷时,这时候 o1 紧跟着 o2 走过的路径;若前方发现雷时,需要排除掉,以此类推,直到走完。
实现的思路:先把需要删除节点的链表进行递归到底进行展示出来,也就是一直递归到底,然后在回归的时候,当 p == null 说明了已经到了链表的底部了,直接返回 null 就好了。需要来判断该节点的值是否需要删除:若不需要删除的节点,在回归的时候需要返回自己的节点,然后需要更新该节点的指向。若需要删除的节点,在回归的时候直接返回 下一个节点。
代码如下:
private Node recursion1(Node p, int value) { if (p == null) { return null; } if (p.value == value) { return recursion1(p.next, value); }else { p.next = recursion1(p.next, value); return p; } }结合代码来具体的实现流程:
介绍两种方式来实现该算法:
一、使用递归来实现
二、使用快慢指针来实现
实现思路:先递出到底 p == null 返回 0 ,接着然后每一次回归都对当前的 i 进行 i++,再来判断是否 i == n,但是我们细想一下,我们得到了 i == n 这个要删除的节点是不是没有什么用,因此,我们实际需要找的节点是 n + 1,当 i == n + 1 时,就可以删除倒数第 n 个节点了 p.next = p.next.next 这样就删除了节点了。
代码如下:
//删除倒数第 n 个节点(递归法) public List deleteCount(List list, int n) { recursion(list.hand,n); return list; } private int recursion(Node p, int n) { if (p == null) { return 0; } int i = recursion(p.next, n); i++; if (i == n + 1) { p.next = p.next.next; } return i; }需要注意的是,这里一定要用带上哨兵的链表,原因是:当我要删除的节点是第一个的时候,没哨兵是完成不了这个操作的。
思路:先定义两个 fast、slow 快慢指针,一开的时候都指向哨兵节点,然后让 slow 先跑 n+1个节点,然后就两个指针 一起跑,循环的结束条件为: slow == null ,因为当 slow == null是,fast.next 刚好指向了要删除的节点,那么直接就用 fast.next = fast.next.next 这就把第 n 个节点删除掉了。
代码如下:
//删除倒数第n个节点(快慢指针) public List removeFastSlowPointers(List list, int n) { list.hand = fastSlowPointers(list.hand,n); return list; } private Node fastSlowPointers(Node hand, int n) { Node temp = hand; Node fast = hand; Node slow = hand; for (int i = 0; i < n + 1; i++) { slow = slow.next; } while (slow != null) { slow = slow.next; fast = fast.next; } fast.next = fast.next.next; return temp; }这里需要注意的是,当要删除第 1 个节点的时候,若没有哨兵节点的时候,是完成不了这个操作的。还有需要注意的是,关于要删除第 n 个节点,实际要找到第 n+1 个节点才能对第 n 个节点进行删除。
- import java.util.Iterator;
-
- public class List implements Iterable
{ - private Node hand;
-
- static class Node {
- public int value;
- public Node next;
-
- public Node() {
- }
-
- public Node(int value, Node next) {
- this.value = value;
- this.next = next;
- }
-
- }
-
- public List() {
- hand = new Node(0,null);
- }
-
- @Override
- public Iterator
iterator() { - return new Iterator
() { - Node p = hand.next;
- @Override
- public boolean hasNext() {
- return p != null;
- }
-
- @Override
- public Integer next() {
- int value = p.value;
- p = p.next;
- return value;
- }
- };
- }
-
-
- //头插节点
- public void addFirst(int value) {
- hand.next = new Node(value,hand.next);
- }
-
- //尾插节点
- public void addLst(int value) {
- Node p = hand;
- while (p.next != null) {
- p = p.next;
- }
- p.next = new Node(value,null);
- }
-
-
- //根据值来删除节点
- public void removeValue( List list, int value) {
- Node o1 = list.hand;
- Node o2 = list.hand.next;
- while (o2 != null) {
-
- if (o2.value == value) {
- o1.next = o2.next;
- o2 = o1.next;
- }else {
- o1 = o2;
- o2 = o2.next;
- }
- }
-
- }
-
- //根据值来删除节点(递归实现)
- public List removeRecursion(List list ,int value) {
- Node p = list.hand.next;
- Node tp = recursion1(p,value);
- list.hand.next = tp;
- return list;
- }
-
- private Node recursion1(Node p, int value) {
-
- if (p == null) {
- return null;
- }
- if (p.value == value) {
- return recursion1(p.next, value);
- }else {
- p.next = recursion1(p.next, value);
- return p;
- }
- }
-
-
- //删除倒数第n个节点(递归法)
- public List deleteCount(List list, int n) {
- recursion(list.hand,n);
- return list;
- }
-
- private int recursion(Node p, int n) {
-
- if (p == null) {
- return 0;
- }
- int i = recursion(p.next, n);
- i++;
- if (i == n + 1) {
- p.next = p.next.next;
- }
-
- return i;
- }
-
-
- //删除倒数第n个节点(快慢指针)
-
- public List removeFastSlowPointers(List list, int n) {
- list.hand = fastSlowPointers(list.hand,n);
- return list;
- }
-
- private Node fastSlowPointers(Node hand, int n) {
- Node temp = hand;
- Node fast = hand;
- Node slow = hand;
- for (int i = 0; i < n + 1; i++) {
- slow = slow.next;
- }
- while (slow != null) {
- slow = slow.next;
- fast = fast.next;
- }
- fast.next = fast.next.next;
- return temp;
- }
-
- }
