重启人生计划-且随风行

news2024/9/21 14:52:00

🥳🥳🥳 茫茫人海千千万万,感谢这一刻你看到了我的文章,感谢观赏,大家好呀,我是最爱吃鱼罐头,大家可以叫鱼罐头呦~🥳🥳🥳

如果你觉得这个【重启人生计划】对你也有一定的帮助,加入本专栏,开启新的训练计划,漫长成长路,千锤百炼,终飞升巅峰!无水文,不废话,唯有日以继日,终踏顶峰! ✨✨欢迎订阅本专栏✨✨

❤️❤️❤️ 最后,希望我的这篇文章能对你的有所帮助! 愿自己还有你在未来的日子,保持学习,保持进步,保持热爱,奔赴山海! ❤️❤️❤️

🔥【重启人生计划】第零章序·大梦初醒🔥

🔥【重启人生计划】第壹章序·明确目标🔥

🔥【重启人生计划】第贰章序·勇敢者先行🔥

🔥【重启人生计划】第叁章序·拒绝内耗🔥

🔥【重启人生计划】第肆章序·积蓄星火🔥

🔥【重启人生计划】第伍章序·浮舟沧海🔥

序言

大家好,我是最爱吃鱼罐头,距离离职已经过去一个月了,目前进度为6,打算重新找工作倒计时24天,当然这其中也会去投递面试。

且行且忘且随风,且行且看且从容。

今日回顾

今天在学习过程中,遇到几个难点,第一,链表花费的时间比较长,因为我做了一些详细的图解,加上自己的理解,从早上一直干到下午才弄完,感觉后续不能这么搞了,除非你们觉得这个图解或者解题思路不错的话,我就会继续做下去。

今天下午的面试题有点难度,像主从同步,binlog啥的,我都得刷一天视频来复习下,才能更好的掌握。明天会看下视频,找下资料去补充下。

回文链表

回文链表📍

回文链表就是以链表中间为中心,两边对称。即 1->2->2->1 ,可以看出从中间隔开两边对称。所以这道题的关键:

  1. 找到中间结点,可以以链表的中间结点 📍这道题为例,找出中间结点;
  2. 如果是回文链表,那我们可以反转后半部分,即2->1这部分,我们将其反转就变成1->2;
  3. 1->2 || 1->2,这样我们可以用后半部分和前半部分进行一一比较,如果有一处不同,就是为false。

代码实现:

package com.ygt.day7;

import com.ygt.day4.ListNode;

/**
 * 234. 回文链表
 * https://leetcode.cn/problems/palindrome-linked-list/description/
 * 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表.如果是,返回 true ;否则,返回 false 。
 * 输入:head = [1,2,2,1]
 * 输出:true
 * @author ygt
 * @since 2024/8/17
 */
public class IsPalindrome {
    public static void main(String[] args) {
        ListNode node5 = new ListNode(1);
        ListNode node4 = new ListNode(2, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node = new ListNode(1, node2);

        System.out.println(new IsPalindrome().isPalindrome(node));
    }

    public boolean isPalindrome(ListNode head) {
        if(head == null || head.next == null) {
            return true;
        }

        // 1. 找到中间结点
        // 注意,fast = head.next,为了找到在偶数的中间结点的前一个结点,方便反转。
        ListNode slow = head, fast = head.next;

        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        // 2. 反转后半部分
        ListNode preNode = slow, curNode = slow.next;
        while (curNode.next != null) {
            ListNode nextNode = curNode.next;
            curNode.next = nextNode.next;
            nextNode.next = preNode.next;
            preNode.next = nextNode;
        }

        // 3. 一一比较
        ListNode firstNode = head;
        while ((preNode = preNode.next) != null) {
            if(firstNode.val != preNode.val) {
                return false;
            }
            firstNode = firstNode.next;
        }

        return true;
    }
}

最后注意虚拟头结点:

链表的一大问题就是操作当前结点必须要找前一个结点才能操作。这就造成了,头结点的尴尬,因为头结点没有前一个结点了。

每次对应头结点的情况都要单独处理,所以使用虚拟头结点的技巧,就可以解决这个问题。而且很多链表的题目中,都大多数需要用到虚拟头结点。

旋转链表

旋转链表📍

先将给定的链表连接成环,然后将指定位置断开,得到新的起始结点。

注意:

在我们观察案例2的时候,我们可以发现此时的 k = 4,而链表的长度为3,在向右移动到第三步的时候,可以发现,链表变回了原状,第四步的操作也就和第一步的操作一致,那我们是不是可以发现一个规律,我们仅需要向右移动k % n 次就行了即取模运算。因为每次移动n次或者n的倍数次的话,链表就会变为原状,浪费时间,所以我们只需要移动k % n 次即可,而当发现取模后得到结果为0,就直接返回当前结点即可。

特别写下java的取模运算的结果:

System.out.println(4 % 3);   // 1 ==> k = 1
System.out.println(5 % 3);	 // 2 ==> k = 2
System.out.println(6 % 3);	 // 0 ==> k = 0
主要步骤:
  1. 首先计算链表的长度,得到链表n的值,并确定好链表的尾结点tailNode;
  2. 重新计算k的值,得出是否需要继续进行旋转移动操作;
  3. 遍历找到链表最后第k个的结点,即n - k,即旋转的最后一个结点的前一个结点preNode;
  4. 将tailNode的next指向首结点head,而preNode的next置空截断,指向null;
  5. 最终完成链表的旋转。
图解

我们根据步骤画出一个大概的图解过程:

动图图解

为了更方便查看图解过程,做了个动画:

代码实现:

package com.ygt.day7;

import com.ygt.day4.ListNode;

/**
 * 61. 旋转链表
 * https://leetcode.cn/problems/rotate-list/description/
 * 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
 * 示例 1:
 * 输入:head = [1,2,3,4,5], k = 2
 * 输出:[4,5,1,2,3]
 * @author ygt
 * @since 2024/8/17
 */
public class RotateRight {
    public static void main(String[] args) {
        ListNode node5 = new ListNode(5);
        ListNode node4 = new ListNode(4, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node = new ListNode(1, node2);

        // 打印查看当前效果
        ListNode.print(node);

        ListNode listNode = new RotateRight().rotateRight(node, 2);
        System.out.println();

        // 打印查看当前效果
        ListNode.print(listNode);
    }

    public ListNode rotateRight(ListNode head, int k) {
        // 进行校验,如果k = 0或者链表为空,或者链表的next为空,都可以直接返回当前结点
        if(k == 0 || head == null || head.next == null) {
            return head;
        }

        // 在我们查看案例2的时候,可以发现一个规律,假设链表的长度为n,当向右移动次数k ≥ n时,并且k的值可能会很大,
        // 所以我们只要移动k % n次即可。而且每次n(或者n的倍数)次移动都是链表的原状态,
        // 所以推导出新链表的头节点位置为原链表的第n - (k % n)个节点(即从0开始计数)。

        // 通过第一次遍历得到链表的长度,还有链表的末尾结点
        int size = 1;
        ListNode tailNode = head;
        while(tailNode.next != null) {
            size++;
            tailNode = tailNode.next;
        }

        // 通过取模计算,重新得到k的值。
        k = k % size;

        // 判断是否为n的倍数,是就直接返回即可
        if(k == 0) {
            return head;
        }

        // 寻找链表最后第k个的结点 preNode
        ListNode preNode = head;
        // 由于当前preNode为head结点,多计算了一位,所以需要size - k - 1。
        for (int i = 0; i < (size - k - 1); i++) {
            preNode = preNode.next;
        }

        // 尾结点闭环
        tailNode.next = head;
        // 新的起始结点
        head = preNode.next;
        // 截断preNode,置为null
        preNode.next = null;
        return head;
    }
}

两两交换链表中的节点

两两交换链表中的节点📍

这道题的思路:

  1. 创建虚拟头结点,能更好的移动头结点;
  2. 题目要求不修改节点内部的值的情况下完成本题,拒绝你这个偷鸡的想法;
  3. 循环遍历,两两交换即可,这道题的思路很简单。

代码实现:

package com.ygt.day7;

import com.ygt.day4.ListNode;

/**
 * 24. 两两交换链表中的节点
 * https://leetcode.cn/problems/swap-nodes-in-pairs/description/
 * 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
 * 输入:head = [1,2,3,4]
 * 输出:[2,1,4,3]
 * @author ygt
 * @since 2024/8/17
 */
public class SwapPairs {
    public static void main(String[] args) {
        ListNode node5 = new ListNode(5);
        ListNode node4 = new ListNode(4, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node = new ListNode(1, node2);

        // 打印查看当前效果
        ListNode.print(node);

        ListNode listNode = new SwapPairs().swapPairs(node);
        System.out.println();

        // 打印查看当前效果
        ListNode.print(listNode);
    }

    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        }

        // 1. 创建虚拟头结点
        ListNode dummyNode = new ListNode(-1, head);
        ListNode curNode = dummyNode.next, preNode = dummyNode;

        // 循环交换
        while (curNode != null) {
            // 需要判断是否还有后续结点
            if(curNode.next != null) {
                // 交换
                ListNode nextNode = curNode.next;
                curNode.next = nextNode.next;
                nextNode.next = preNode.next;
                preNode.next = nextNode;
            }

            // 最后复位
            preNode = curNode;
            curNode = curNode.next;
        }

        return dummyNode.next;
    }
}

合并两个有序链表

合并两个有序链表📍

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这道题的主要思路:

  1. 创建虚拟头结点,作为合并后的新链表头结点的前一个结点;
  2. 比较两个链表的每一个结点的大小,小的就添加到新链表的末尾处,直到某一个链表已经遍历结束;
  3. 最后补充剩余结点链表到新链表的末尾。

代码实现:

package com.ygt.day7;

import com.ygt.day4.ListNode;

/**
 * 21. 合并两个有序链表
 * https://leetcode.cn/problems/merge-two-sorted-lists/
 * 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
 * 输入:l1 = [1,2,4], l2 = [1,3,4]
 * 输出:[1,1,2,3,4,4]
 * @author ygt
 * @since 2024/8/17
 */
public class MergeTwoLists {
    public static void main(String[] args) {

        ListNode node = new ListNode(1, new ListNode(2, new ListNode(4)));
        ListNode node2 = new ListNode(1, new ListNode(3, new ListNode(4)));

        // 打印查看当前效果
            ListNode.print(node);

        ListNode listNode = new MergeTwoLists().mergeTwoLists(node, node2);
            System.out.println();

        // 打印查看当前效果
            ListNode.print(listNode);
    }

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        // 判断两个链表是否为空
        if(list1 == null) {
            return list2;
        }
        if(list2 == null) {
            return list1;
        }

        // 1. 创建虚拟头结点,作为合并后的新链表头结点的前一个结点
        ListNode dummyNode = new ListNode(-1);

        ListNode head = dummyNode;

        // 2. 比较两个链表的每一个结点的大小,小的就添加到新链表的末尾处,直到某一个链表已经遍历结束;
        while (list1 != null && list2 != null) {
            if(list1.val <= list2.val) {
                head.next = list1;
                list1 = list1.next;
            }else {
                head.next = list2;
                list2 = list2.next;
            }
            head = head.next;
        }

        // 3. 最后补充剩余结点链表到新链表的末尾。
        head.next = list1 == null ? list2: list1;
        return dummyNode.next;
    }
}

小结算法

今天的算法是有点难度,得多思考下,才能做出来,当然大神的你无需耗费更多的精神就做出来啦。

明日内容

明天刷一下MySQL高级的面试题,如主从以及binlog。

🌸 完结

最后,相关算法的代码也上传到gitee或者github上了。

乘风破浪会有时 直挂云帆济沧海

希望从明天开始,一起加油努力吧,成就更好的自己。

🥂 虽然这篇文章完结了,但是我还在,永不完结。我会努力保持写文章。来日方长,何惧车遥马慢!✨✨✨

💟 感谢各位看到这里!愿你韶华不负,青春无悔!让我们一起加油吧! 🌼🌼🌼

💖 学到这里,今天的世界打烊了,晚安!🌙🌙🌙

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2048860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Element UI详解

目录 Element UIElement UI 简介开发使用开发指南概述总结 设计原则组件使用特性使用场景优势不足 Element UI Element UI 简介 Element UI 是由饿了么前端团队开发的一套基于 Vue.js 的桌面端组件库。它提供了一系列丰富的 UI 组件&#xff0c;用于快速搭建企业级的 Web 应用…

RCE编码绕过--php://filter妙用

目录 代码 如何绕过 payload构造 代码 <?php $content <?php exit; ?>; $content . $_POST[txt]; file_put_contents($_POST[filename],$content); 当你想要输入代码的时候前面会有<?php exit;?>;&#xff0c;代码没有办法执行下去&#xff0c;所以…

day32+学习记录

一.算法练习 509.斐波那契数 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xf…

(待会删)分享9款一键生成原创论文在线使用软件

在当前的学术研究和写作环境中&#xff0c;AI技术的应用已经变得越来越普遍。其中&#xff0c;一键生成原创论文的在线软件更是为学者们提供了极大的便利。本文将重点介绍一款备受推荐的AI原创论文写作平台——千笔-AIPassPaPer&#xff0c;并分享其他几款优秀的同类软件。 千…

政务大数据解决方案(五)

政务大数据解决方案旨在通过建立统一的数据平台&#xff0c;将各政府部门的数据资源进行有效整合与智能分析&#xff0c;利用先进的数据处理和人工智能技术实现对社会动态的实时监测和精准预测&#xff0c;从而优化政府决策、提升公共服务效率和透明度。该方案涵盖数据的采集、…

每日OJ_牛客HJ75 公共子串计算

目录 牛客HJ75 公共子串计算 解析代码 牛客HJ75 公共子串计算 公共子串计算_牛客题霸_牛客网 解析代码 求最大公共子串&#xff0c;使用递推实现 假设 x(i)&#xff1a;字符串第i个字符 y(j)&#xff1a;字符串第j个字符 dp[i][j]&#xff1a;以x(i)&#xff0c;y(j)结尾的最…

XSS-games

XSS 1.XSS 漏洞简介2.XSS的原理3.XSS的攻击方式4.XSS-GAMESMa SpaghetJefffUgandan KnucklesRicardo MilosAh Thats HawtLigmaMafiaOk, BoomerWW3svg 1.XSS 漏洞简介 ​ XSS又叫CSS&#xff08;Cross Site Script&#xff09;跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Sc…

XSS反射实战

目录 1.XSS向量编码 2.xss靶场训练&#xff08;easy&#xff09; 2.1第一关 2.2第二关 方法一 方法二 2.3第三关 2.4第四关 2.5第五关 2.6第六关 2.7第七关 第一种方法&#xff1a; 第二种方法&#xff1a; 第三个方法&#xff1a; 2.8第八关 1.XSS向量编码 &…

二叉树进阶之二叉搜索树:一切的根源

前言&#xff1a; 在学完了简单的容器与C面向对象的三大特性之后&#xff0c;我们首先接触的就是map与set两大容器&#xff0c;但是这两个容器底层实现的原理是什么呢&#xff1f;我们不而知&#xff0c;今天&#xff0c;主要来为学习map与set的底层原理而打好基础&#xff0c…

【精选】学生考勤管理系统设计与实现(源码+辅导+设计)

目录&#xff1a; 系统介绍&#xff1a; 第2章 开发技术介绍 2.1 B/S结构 2.2 Java语言 2.3 springboot框架 2.4 MySQL数据库 系统设计 系统的总体功能设计 系统实现界面&#xff1a; 3.视频演示 系统测试 测试概述 测试结果 参考代码&#xff1a; 为什么选择我&am…

【数据结构】PTA 单链表逆转 C语言

本题要求实现一个函数&#xff0c;将给定的单链表逆转。 函数接口定义&#xff1a; List Reverse( List L ); 其中List结构定义如下&#xff1a; typedef struct Node *PtrToNode; struct Node {ElementType Data; /* 存储结点数据 */PtrToNode Next; /* 指向下一个结点的…

进程间通信学习记录(IPC 机制以及共享内存)

0.System V IPC机制&#xff1a; ①.IPC对象包含&#xff1a;共享内存、消息队列和信号灯集。 ②.每个IPC对象有唯一的ID。 ③.IPC对象创建后一直存在&#xff0c;直到被显示地删除。 ④.每一个IPC对象有一个关联的KEY。&#xff08;其他进程通过KEY访问对应的IPC对象&#xff…

XSS和DOM破坏案例

XSS案例 环境地址&#xff1a;XSS Game - Learning XSS Made Simple! | Created by PwnFunction 1.Ma Spaghet! 源码&#xff1a; <!-- Challenge --> <h2 id"spaghet"></h2> <script>spaghet.innerHTML (new URL(location).searchParam…

【LiteX】【开发板】【BoChenK7】使用Python开发FPGA【SDRAM/DDR/Bootloader】

目录 开发板介绍下载仓库工程设计代码实现 工程构建启动测试Memory测速Bootloader&#xff08;裸机BareMetal程序&#xff09;Bootloader&#xff08;Linux OS&#xff09; 开发板信息 开发板介绍 手头目前只有一个购买的BoChenK7开发板&#xff0c;后续会用它来进行LiteX FPG…

政务大数据解决方案(九)

政务大数据解决方案旨在通过构建高效的数据处理与分析系统&#xff0c;全面整合政府各部门数据资源&#xff0c;运用尖端技术进行深入挖掘与智能分析&#xff0c;为政府决策提供科学、精准的数据支撑&#xff0c;优化政策制定与执行流程&#xff0c;同时通过加强数据安全与隐私…

基于Kotlin Multiplatform实现静态文件服务器(一)

本文将介绍如何基于Kotlin Multiplatform、Jetpack Compose实现静态文件服务器&#xff0c;并运行在Android、Windows以及Linux&#xff08;暂不支持server和mac&#xff09;。 创建KMP&#xff08;Kotlin Multiplatform&#xff09;项目 环境设置 安装Android Studiio 2023.…

Java二十三种设计模式-迭代子模式(16/23)

迭代器模式&#xff1a;顺序访问集合的稳健方式 引言 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许顺序访问一个集合对象中的各个元素&#xff0c;而不需要暴露集合的底层表示。 基础知识&#xff0c;java设计模式总体来说设计…

ESP32-C3在MQTT访问时出现“transport_base: Poll timeout or error”问题的分析(1)

笔者最近在测试时,突然遇到了以下错误: 网上看过一些帖子,要么就是只提出遇到了相同问题,但没有解答。如:transport_base: Poll timeout or error, errno=Connection already in progress - ESP32 Forum 要么就是和本问题类似,但不完全相同的问题。如: TRANSPORT_BASE:…

Tomcat学习进阶

目录 Apache Tomcat架构配置线程模型Tomcat 的类加载机制类加载器层次结构类加载流程 Tomcat 的优化策略Tomcat 的集群部署Tomcat故障排查 Apache Tomcat 架构配置 Apache Tomcat是一个开源的Java Servlet容器和Web服务器&#xff0c;它实现了Java EE规范中的Servlet和JSP API。…

mysql中的innodb存储结构

什么是InnoDB存储引擎 InnoDB是MySQL的默认存储引擎&#xff0c;它是一个事务安全的存储引擎&#xff0c;支持行级锁定和外键约束。InnoDB为MySQL提供了高性能、高可靠性和高可用性的解决方案。 InnoDB 的核心特点和功能 事务支持&#xff1a;InnoDB支持ACID事务特性&#x…