算法日常记录

1. 链表

1.1 删除链表的倒数第 N 个结点

问题描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

输入:head = [1,2,3,4,5], n = 2

输出:[1,2,3,5]

思路:先让fast跑n步,然后slow和fast再一起跑,fast到达末尾时,slow刚好为倒数第n+1个节点,下面代码使用了虚拟结点,所以跑n+1步。

1 -> 2 -> 3 -> 4 -> 5-> null

删除倒数第二个结点,即4;那么要使得3的指针指向5,即3 -> 5,在原链表上表现为 3.next = 3.next.next;

即删除结点的前一个结点 指向 该结点的后一个结点

采用双指针进行完成:快指针移动到n+1的位置后,慢指针开始移动

自测代码:

java 复制代码
/**
 * 删除链表的倒数第 N 个结点
 * 输入:head = [1,2,3,4,5], n = 2
 * 输出:[1,2,3,5]
 *
 * 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; }
 * }
 */
public class RemoveNthFromEnd {
    public static void main(String[] args) {

        ListNode head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
        ListNode result = removeNthFromEnd(head,2);
        ListNode curr = result;
        while (curr != null) {
            System.out.println(curr.val);
            curr = curr.next;
        }
    }

    /*
     1 -> 2 -> 3 -> 4 -> 5-> null
     删除倒数第二个结点,即4;那么要使得3的指针指向5,即3 -> 5,在原链表上表现为 3.next = 3.next.next;
     即删除结点的前一个结点 指向 该结点的后一个结点
     采用双指针进行完成:快指针移动到n+1的位置后,慢指针开始移动

     */
    private static ListNode removeNthFromEnd(ListNode head, int n) {
        //为避免要删除结点没有前一个结点,使用虚拟结点指向head
        ListNode dummy = new ListNode(0,head);
        ListNode fast = dummy;
        ListNode slow = dummy;
        //fast结点先移动到n节点的后一个结点位置
        for (int i = 0; i <= n; i++) {
            fast = fast.next;
        }
        //然后fast和slow结点一起移动,知道fast为null
        while (fast != null) {
            fast = fast.next;
            slow = slow.next;
        }

        // 此时 slow 的位置就是待删除元素的前一个位置
        if(slow.next != null){
            slow.next = slow.next.next;
        }
        return dummy.next;
    }

力扣代码:

java 复制代码
/**
 * 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) {
        //新建一个虚拟头节点指向head
         ListNode dummy = new ListNode(0, head);
         //快慢指针指向虚拟头节点
         ListNode fast = dummy;
         ListNode slow =dummy;
         //快指针先移动n+1个节点,只要快慢指针相差 n 个结点即可
         for(int i=0; i<=n;i++){
            fast = fast.next;
         }
         //此时,快慢指针一起移动,快指针为null时,慢指针位于n的前一个节点
         while(fast != null){
            fast = fast.next;
            slow = slow.next;
         }
         // 此时 slow 的位置就是待删除元素的前一个位置
         if(slow.next != null){
            slow.next = slow.next.next;
         }

         return dummy.next;
    }
}
相关推荐
Boilermaker199228 分钟前
[Java 并发编程] Synchronized 锁升级
java·开发语言
Cherry的跨界思维41 分钟前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
MM_MS44 分钟前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
独自破碎E1 小时前
【二分法】寻找峰值
算法
alonewolf_991 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
一嘴一个橘子1 小时前
spring-aop 的 基础使用(啥是增强类、切点、切面)- 2
java
sheji34161 小时前
【开题答辩全过程】以 中医药文化科普系统为例,包含答辩的问题和答案
java
mit6.8242 小时前
位运算|拆分贪心
算法
ghie90902 小时前
基于MATLAB的TLBO算法优化实现与改进
开发语言·算法·matlab
恋爱绝缘体12 小时前
2020重学C++重构你的C++知识体系
java·开发语言·c++·算法·junit