• 【算法合集】学习算法第一天(链表篇)


    ✅🎡个人主页:程序猿追

    ✅🎡系列专栏:算法合集

    ✅🎡目前状态:创建Java学习之路(零基础到就业实战)系列,目前更新到JAVAWEB开发

    ✅🎡作者简介:大家好,我是程序猿追,全栈领域新星创作者,算法爱好者,常在作者周榜排名前30,某不知名的 ACMer

    ✅🎡推荐一款刷题面试找工作三不误的网站——牛客网

    ✅🎡个人名言:不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!

    目录

    🍟前言

    🍟反转链表

    🍔题解代码

    🍟链表区间反转

    🍔题解代码

    🍟链表的奇偶重排

    🍔题解代码

    🍟链表中的节点每k个一组翻转

    🍔题解代码

    前言

           哈喽,大家好,我是程序猿追,众所周知算法是比较复杂又基础的学科,每个学编程的人都会学习大量的算法。无论在我们面试还是笔试算法是必不可少的,我们打开某招聘网站,发现薪资待遇都很友好。

     再看看某大厂的面试题

     

     无论是找工作,还是打比赛,搞科研,算法占据了主要地位,在我刚开始学习算法时(我还是一个小菜鸡时),我的一个大牛学长(已经拿到了心仪的 offer)推荐我一个神奇的神奇——我是神奇,里面大厂的算法题、面试题以及面经应有尽有,我们来看看吧。

    反转链表

    🎀描述

    给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。

    数据范围: 0 ≤ n ≤ 1000

    要求:空间复杂度 O(1),时间复杂度 O(n)。

    如当输入链表{1,2,3}时,

    经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。

    以上转换过程如下图所示:

     🎀示例1

    输入:{1,2,3}

    返回值:{3,2,1}

     🎀示例2

    输入:{}

    返回值:{}

    说明:空链表则输出空

    题解代码

    1. public class Solution {
    2. public ListNode ReverseList(ListNode head) {
    3. //处理空链表 fast-template
    4. if (head == null)
    5. return null;
    6. ListNode cur = head;
    7. ListNode pre = null;
    8. while (cur != null) {
    9. //断开链表,要记录后续一个
    10. ListNode temp = cur.next;
    11. //当前的next指向前一个
    12. cur.next = pre;
    13. //前一个更新为当前
    14. pre = cur;
    15. //当前更新为刚刚记录的后一个
    16. cur = temp;
    17. }
    18. return pre;}
    19. }

    链表内指定区间反转

    💎描述

    将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n),空间复杂度 O(1)O(1)。
    例如:
    给出的链表为 NULL1→2→3→4→5→NULL, m=2,n=4m=2,n=4,
    返回  NULL1→4→3→2→5→NULL.
     

    数据范围: 链表长度 0 < size ≤ 1000,0 < size0 < m ≤ n ≤ size,链表中每个节点的值满足 ∣val∣≤1000

    要求:时间复杂度 O(n) ,空间复杂度 O(n)

    进阶:时间复杂度 O(n),空间复杂度 O(1)

    💎示例1

    输入:{1,2,3,4,5},2,4

    返回值:{1,4,3,2,5}

    💎示例2

    输入:{5},1,1

    返回值:{5}

    题解代码

    1. import java.util.*;
    2. public class Solution {
    3. public ListNode reverseBetween (ListNode head, int m, int n) {
    4. //加个表头 fast-template
    5. ListNode res = new ListNode(-1);
    6. res.next = head;
    7. //前序节点
    8. ListNode pre = res;
    9. //当前节点
    10. ListNode cur = head;
    11. //找到m
    12. for (int i = 1; i < m; i++) {
    13. pre = cur;
    14. cur = cur.next;
    15. }
    16. //从m反转到n
    17. for (int i = m; i < n; i++) {
    18. ListNode temp = cur.next;
    19. cur.next = temp.next;
    20. temp.next = pre.next;
    21. pre.next = temp;
    22. }
    23. //返回去掉表头
    24. return res.next;}
    25. }

    链表的奇偶重排

    💕描述

    给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。

    注意是节点的编号而非节点的数值。

    数据范围:节点数量满足 0 ≤ n ≤ 10^5,节点中的值都满足 0 ≤ val ≤ 1000

    要求:空间复杂度 O(n),时间复杂度 O(n)

    💕示例1

    输入:{1,2,3,4,5,6}

    返回值:{1,3,5,2,4,6}

    💕说明:

    1->2->3->4->5->6->NULL

    重排后为

    1->3->5->2->4->6->NULL

    💕示例2

    输入:{1,4,6,3,7}

    返回值:{1,6,7,4,3}

    💕说明:

    1->4->6->3->7->NULL

    重排后为

    1->6->7->4->3->NULL
    奇数位节点有1,6,7,偶数位节点有4,3。重排后为1,6,7,4,3

    💕备注:

    链表长度不大于200000。每个数范围均在int内。

    题解代码

    1. import java.util.*;
    2. public class Solution {
    3. public ListNode oddEvenList (ListNode head) {
    4. //如果链表为空,不用重排 fast-template
    5. if(head == null)
    6. return head;
    7. //even开头指向第二个节点,可能为空
    8. ListNode even = head.next;
    9. //odd开头指向第一个节点
    10. ListNode odd = head;
    11. //指向even开头
    12. ListNode evenhead = even;
    13. while(even != null && even.next != null){
    14. //odd连接even的后一个,即奇数位
    15. odd.next = even.next;
    16. //odd进入后一个奇数位
    17. odd = odd.next;
    18. //even连接后一个奇数的后一位,即偶数位
    19. even.next = odd.next;
    20. //even进入后一个偶数位
    21. even = even.next;
    22. }
    23. //even整体接在odd后面
    24. odd.next = evenhead;
    25. return head;}
    26. }

    链表中的节点每k个一组翻转

    🎉描述

    将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
    如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
    你不能更改节点中的值,只能更改节点本身。

    数据范围: 0 ≤ n ≤ 2000 , 1 ≤ k ≤ 2000 ,链表中每个元素都满足 0 ≤ val ≤ 1000
    要求空间复杂度 O(1),时间复杂度 O(n)

    🎉例如:

    给定的链表是 1→2→3→4→5

    对于 k = 2, 你应该返回 2→1→4→3→5

    对于 k = 3, 你应该返回 3→2→1→4→5

    🎉示例1

    输入:{1,2,3,4,5},2

    返回值:{2,1,4,3,5}

    🎉示例2

    输入:{},1

    复制返回值:{}

    1. import java.util.*;
    2. public class Solution {
    3. public ListNode reverseKGroup (ListNode head, int k) {
    4. //找到每次翻转的尾部 fast-template
    5. ListNode tail = head;
    6. //遍历k次到尾部
    7. for (int i = 0; i < k; i++) {
    8. //如果不足k到了链表尾,直接返回,不翻转
    9. if (tail == null)
    10. return head;
    11. tail = tail.next;
    12. }
    13. //翻转时需要的前序和当前节点
    14. ListNode pre = null;
    15. ListNode cur = head;
    16. //在到达当前段尾节点前
    17. while (cur != tail) {
    18. //翻转
    19. ListNode temp = cur.next;
    20. cur.next = pre;
    21. pre = cur;
    22. cur = temp;
    23. }
    24. //当前尾指向下一段要翻转的链表
    25. head.next = reverseKGroup(tail, k);
    26. return pre;}
    27. }

    不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!

  • 相关阅读:
    CleanMyMac X2023测评是不是恶意软件?
    第四篇:Sentinel限流核心逻辑过程分析
    软考网络工程师每日一练10.20
    Higress 基于自定义插件访问 Redis
    JAVA面试题——创建线程的三种方式
    ESWC 2018 | R-GCN:基于图卷积网络的关系数据建模
    【JavaSE专栏55】Java集合类HashTable解析,基于哈希表实现的唯一性键值对存储数据结构
    软考 系统架构设计师系列知识点之设计模式(2)
    大数据开发基础实验三
    笔试练习day01
  • 原文地址:https://blog.csdn.net/aasd23/article/details/125749684