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

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


目录

🍟前言

🍟反转链表

🍔题解代码

🍟链表区间反转

🍔题解代码

🍟链表的奇偶重排

🍔题解代码

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

🍔题解代码

前言

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

image.gif

再看看某大厂的面试题

image.gif

无论是找工作,还是打比赛,搞科研,算法占据了主要地位,我们来看看吧。

反转链表

🎀描述

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

数据范围: 0 ≤ n ≤ 1000

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

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

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

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

image.gif编辑

🎀示例1

输入:{1,2,3}

返回值:{3,2,1}

🎀示例2

输入:{}

返回值:{}

说明:空链表则输出空

题解代码

public class Solution {
    public ListNode ReverseList(ListNode head) {
        //处理空链表 fast-template
        if (head == null)
            return null;
        ListNode cur = head;
        ListNode pre = null;
        while (cur != null) {
            //断开链表,要记录后续一个
            ListNode temp = cur.next;
            //当前的next指向前一个
            cur.next = pre;
            //前一个更新为当前
            pre = cur;
            //当前更新为刚刚记录的后一个
            cur = temp;
        }
        return pre;}
}

image.gif

链表内指定区间反转

💎描述

将一个节点数为 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}

题解代码

import java.util.*;
public class Solution {
    public ListNode reverseBetween (ListNode head, int m, int n) {
        //加个表头 fast-template
        ListNode res = new ListNode(-1);
        res.next = head;
        //前序节点
        ListNode pre = res;
        //当前节点
        ListNode cur = head;
        //找到m
        for (int i = 1; i < m; i++) {
            pre = cur;
            cur = cur.next;
        }
        //从m反转到n
        for (int i = m; i < n; i++) {
            ListNode temp = cur.next;
            cur.next = temp.next;
            temp.next = pre.next;
            pre.next = temp;
        }
        //返回去掉表头
        return res.next;}
}

image.gif

链表的奇偶重排

💕描述

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

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

数据范围:节点数量满足 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内。

题解代码

import java.util.*;
public class Solution {
    public ListNode oddEvenList (ListNode head) { 
        //如果链表为空,不用重排 fast-template
        if(head == null)
            return head;
        //even开头指向第二个节点,可能为空
        ListNode even = head.next;
        //odd开头指向第一个节点
        ListNode odd = head;
        //指向even开头
        ListNode evenhead = even;
        while(even != null && even.next != null){
            //odd连接even的后一个,即奇数位
            odd.next = even.next;
            //odd进入后一个奇数位
            odd = odd.next;
            //even连接后一个奇数的后一位,即偶数位
            even.next = odd.next;
            //even进入后一个偶数位
            even = even.next;
        }
        //even整体接在odd后面
        odd.next = evenhead;
        return head;}
}

image.gif

链表中的节点每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

复制返回值:{}

import java.util.*;
public class Solution {
    public ListNode reverseKGroup (ListNode head, int k) {
         //找到每次翻转的尾部 fast-template
        ListNode tail = head;
        //遍历k次到尾部
        for (int i = 0; i < k; i++) {
            //如果不足k到了链表尾,直接返回,不翻转
            if (tail == null)
                return head;
            tail = tail.next;
        }
        //翻转时需要的前序和当前节点
        ListNode pre = null;
        ListNode cur = head;
       //在到达当前段尾节点前
        while (cur != tail) {
            //翻转
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
       //当前尾指向下一段要翻转的链表
        head.next = reverseKGroup(tail, k);
        return pre;}
}

image.gif

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

image.gif


相关文章
|
8天前
|
算法
【优选算法专栏】专题九:链表--------两两交换链表中的节点
【优选算法专栏】专题九:链表--------两两交换链表中的节点
16 0
|
1月前
|
算法
【数据结构与算法】题解 | #反转链表#
【数据结构与算法】题解 | #反转链表#
|
8天前
|
算法
算法系列--递归(一)--与链表有关(上)
算法系列--递归(一)--与链表有关
18 0
|
3天前
|
机器学习/深度学习 算法 前端开发
Scikit-learn进阶:探索集成学习算法
【4月更文挑战第17天】本文介绍了Scikit-learn中的集成学习算法,包括Bagging(如RandomForest)、Boosting(AdaBoost、GradientBoosting)和Stacking。通过结合多个学习器,集成学习能提高模型性能,减少偏差和方差。文中展示了如何使用Scikit-learn实现这些算法,并提供示例代码,帮助读者理解和应用集成学习提升模型预测准确性。
|
3天前
|
机器学习/深度学习 算法 Python
使用Python实现集成学习算法:Bagging与Boosting
使用Python实现集成学习算法:Bagging与Boosting
15 0
|
8天前
|
算法
算法系列--链表刷题(二)(下)
算法系列--链表刷题(二)(下)
13 0
|
10天前
|
算法
【算法学习--字符串】(不含KMP算法)
【算法学习--字符串】(不含KMP算法)
|
1月前
|
Rust Dart 算法
55.3k star!开源算法教程,附带动画图解,学习算法不再苦恼!
55.3k star!开源算法教程,附带动画图解,学习算法不再苦恼!
|
1月前
|
算法 C++ 计算机视觉
Opencv(C++)学习系列---Laplacian拉普拉斯边缘检测算法
Opencv(C++)学习系列---Laplacian拉普拉斯边缘检测算法
|
1月前
|
算法 C++ 计算机视觉
Opencv(C++)学习系列---Canny边缘检测算法
Opencv(C++)学习系列---Canny边缘检测算法