字节秋招高频算法汇总(高级篇)

在这里插入图片描述

更多大厂面试内容可见 -> http://11come.cn

字节秋招高频算法汇总

接下来讲一下 字节秋招 中的高频算法题,分为三个部分: 基础篇中级篇进阶篇

目的就是为了应对秋招中的算法题,其实过算法题的诀窍就在于 理解的基础上 + 背会

看到一个题目,首先要了解题目考察的算法是什么,这个算法要理解,至于具体实现的话,就靠背会了(多写、多练),没有什么捷径,可以 尝试一个题目手写 3-5 遍 ,加强一下记忆!

还有一点要注意的是,在大厂的笔试中, 可能考察算法的方式是 ACM 模式 ,这一点和力扣上不同,ACM 模式需要我们自己去引入对应的包,以及自己写算法,力扣是将方法框架给定,只需要在方法内写代码就可以了,这一点要注意!

进阶篇

在进阶篇主要考察 多次二分查找反转链表(区间反转)树形 DP(较为复杂) ,如下:

image-20240318230754343

LC 852. 山脉数组的峰顶索引(中等)

题目描述:

符合下列属性的数组 arr 称为 山脉数组

  • arr.length >= 3
  • 存在 i0 < i < arr.length - 1)使得:
    • arr[0] < arr[1] < ... arr[i-1] < arr[i]
    • arr[i] > arr[i+1] > ... > arr[arr.length - 1]

给你由整数组成的山脉数组 arr ,返回满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1] 的下标 i

你必须设计并实现时间复杂度为 O(log(n)) 的解决方案。

输入:arr = [0,1,0]
输出:1

这道题目是让找出山顶的坐标,并且要求时间复杂度为 O(Logn) ,那么显然 二分查找 的时间复杂度符合要求,并且题目中的数组也符合二分查找的 二段性 ,即分为了 左边升序 的数组和 右边降序 的数组

那么如果发现我们当前二分的 mid 点是在 左边升序数组 中,就令 l = mid ,如果发现 mid 点在右边降序数组中,就令 r = mid - 1

最后 r 指针就是山顶的下标

class Solution {public int peakIndexInMountainArray(int[] arr) {int n = arr.length;// 令 l 为第二个点,r 为 n-2 个点// 这样 l-1 就不会小于 0 了int l = 1, r = n - 2;while (l < r) {// 如果 r = mid - 1,则 mid = l + r + 1 >> 1// 如果 r = mid,则 mid = l + r >> 1int mid = l + r + 1 >> 1;// 判断在左边升序还是右边降序if (arr[mid] > arr[mid - 1]) {l = mid;} else {r = mid - 1;}}return r;}
}

LC 92. 反转链表 II(中等)

题目描述:

给你单链表的头指针 head 和两个整数 leftright ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表

image-20240318204422896

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

该题目考察的还是 链表的翻转 ,我们只需要对题目中指定的区间内链表翻转即可

那么只要找到 需要翻转的链表区间 ,将该区间链表翻转,再和前边的区间和后边的区间连接起来即可

那么需要翻转指定的链表区间,就需要 2 个指针:

  • start :当前翻转区间的开始节点
  • end :当前翻转区间的结束节点

翻转之后要和前边、后边的链表区间连接起来,还需要 2 个指针:

  • pre :上一个区间的最后一个节点
  • nextStart :下一个区间的开始节点

4 个指针位置如下图:

image-20240318211208399

这个和中级篇中的 K 个一组翻转链表的题目类似, 代码如下:

/*** 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 reverseBetween(ListNode head, int left, int right) {// 定义一个虚拟节点,方便定位下边 4 个指针的位置ListNode dummy = new ListNode(-1);dummy.next = head;// 上一个区间的最后一个点ListNode pre = dummy;// 下一个区间的第一个点ListNode nextStart = new ListNode(-1);// 翻转区间的第一个点ListNode start = new ListNode(-1);// 翻转区间的最后一个点ListNode end = new ListNode(-1);ListNode cur = dummy;while (cur != null) {left --;if (left == 0) {pre = cur;start = cur.next;}cur = cur.next;}cur = dummy;while (cur != null) {right --;cur = cur.next;if (right == 0) {end = cur;nextStart = cur.next;}}end.next = null;reverse(start);pre.next = end;start.next = nextStart;return dummy.next;}public void reverse(ListNode start) {ListNode last = null;ListNode now = start;while (now != null) {ListNode tmp = now.next;now.next = last;last = now;now = tmp;}}
}

LC 310. 最小高度树(中等)

题目描述:

树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,任何一个没有简单环路的连通图都是一棵树。

给你一棵包含 n 个节点的树,标记为 0n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges 列表(每一个边都是一对标签),其中 edges[i] = [ai, bi] 表示树中节点 aibi 之间存在一条无向边。

可选择树中任何一个节点作为根。当选择节点 x 作为根节点时,设结果树的高度为 h 。在所有可能的树中,具有最小高度的树(即,min(h))被称为 最小高度树

请你找到所有的 最小高度树 并按 任意顺序 返回它们的根节点标签列表。

树的 高度 是指根节点和叶子节点之间最长向下路径上边的数量。

image-20240318212502682

输入:n = 4, edges = [[1,0],[1,2],[1,3]]
输出:[1]
解释:如图所示,当根是标签为 1 的节点时,树的高度是 1 ,这是唯一的最小高度树。

这道题目使用 树形 DP 来做,树形 DP 要么上边的节点使用到了下边节点的状态,要么下边节点使用到了上边节点的状态

这道题目比较复杂,对于一个节点,既使用到了上边、又使用到了下边节点的状态

题目要求我们找到 最小高度 的树,将他们的根节点返回即可,那么如果 暴力 来做的话,只需要去枚举所有的节点,对该节点遍历所有的子树,求出该节点的高度,暴力计算中是会包含许多重复计算的,因此使用 DP 来保存节点的状态,减少计算(暴力解的话,会超时)

要知道一个节点的高度,分为两种情况:

  • 该节点向上走的最大高度
  • 该节点向下走的最大高度

要计算该节点(设为 x)向上走的最大高度,就是计算该节点的父节点(设为 p)的最大高度 + 1,那么 p 的最大高度也分为了两种情况:

  • p 的最大高度是经过 x 的:那么这种情况,在计算 x 的最大高度时,使用到了 p 的最大高度,而 p 的最大高度又是走到 x 了,这样就重复了,所以还需要记录一个数组记录节点的次大高度,这样当 p 的最大高度是走到 x 的话,我们直接使用 p 的次大高度即可
  • p 的最大高度不是经过 x 的:这种情况,就直接使用 p 的最大高度 + 1 来计算 x 的最大高度即可

image-20240318223540112

那么在计算的时候,需要使用 d1[i] 来计算 i 节点的最大高度,使用 d2[i] 计算 i 节点的次大高度,使用 up[i] 计算 i 节点向上的最大高度,使用 p[i] 表示 i 节点最大高度是走向的哪个节点(避免重复的计算)

代码如下:

class Solution {int[] d1;int[] d2;int[] p;int[] up;Map<Integer, List<Integer>> g = new HashMap<>();// 计算 u 节点的最大高度和次大高度public void dfs1(int u, int father) {List<Integer> toNodes = g.getOrDefault(u, new ArrayList<>());for (int i = 0; i < toNodes.size(); i ++) {int x = g.get(u).get(i);if (x == father) continue;dfs1(x, u);int d = d1[x] + 1;if (d >= d1[u]) {d2[u] = d1[u];d1[u] = d;p[u] = x;} else if (d > d2[u]) {d2[u] = d;}}}// 计算 u 节点向上走的最大高度void dfs2(int u, int father) {List<Integer> toNodes = g.getOrDefault(u, new ArrayList<>());for (int i = 0; i < toNodes.size(); i ++) {int x = g.get(u).get(i);if (x == father) continue;if (p[u] == x) up[x] = Math.max(up[u], d2[u]) + 1;else up[x] = Math.max(up[u], d1[u]) + 1;dfs2(x, u);}}public List<Integer> findMinHeightTrees(int n, int[][] edges) {List<Integer> res = new ArrayList<>();d1 = new int[n]; d2 = new int[n];up = new int[n]; p = new int[n];// 先遍历边,将所有的边放到 g 中去,g[u] 表示 u 节点可以到达节点for (int i = 0; i < edges.length; i ++) {int a = edges[i][0];int b = edges[i][1];// a 和 b 节点之间存在一条边,是无向边,因此向 g[a]、g[b] 中都存储一份g.computeIfAbsent(a, k->new ArrayList<>()).add(b);g.computeIfAbsent(b, k->new ArrayList<>()).add(a);}// 计算 u 节点向下走的最大高度和次大高度dfs1(0, -1);// 计算 u 节点向上走的最大高度dfs2(0, -1);// 先找到最低高度int minDepth = n + 1;for (int i = 0; i < n; i ++) {minDepth = Math.min(minDepth, Math.max(up[i], d1[i]));}// 将最低高度的节点加入到结果集中for (int i = 0; i < n; i ++) {if (Math.max(up[i], d1[i]) == minDepth) {res.add(i);}}return res;}
}

LC 121. 买卖股票的最佳时机(简单)

题目描述:

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

这道题目在力扣中有一个系列,都是 买卖股票 问题,可以把相关的题目都看一下

这道题目比较简单,遍历一遍,就就可以计算出来最大利润

代码如下:

class Solution {public int maxProfit(int[] prices) {int n = prices.length;// minv:最低价格// res:结果int minv = prices[0], res = 0;for (int i = 1; i < n; i ++) {minv = Math.min(minv, prices[i]);res = Math.max(res, prices[i] - minv);}return res;}
}

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

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

相关文章

与Apollo共创生态:我和Apollo七周年大会的心路历程

一、写在前面 前几天观看了Apollo七周年大会&#xff0c;给我带来了超多的惊喜&#xff0c;博主想将这份惊喜分享给大家&#xff01; 二、Apollo开放平台 Apollo开放平台秉承其核心理念——开放能力、共享资源、加速创新、持续共赢&#xff0c;致力于推动自动驾驶技术的革新…

《HCIP-openEuler实验指导手册》1.2Apache主页面配置

一、配置服务器监听IP及端口 注释主配置文件“监听IP及端口”部分 cd /etc/httpd/conf cp httpd.conf httpd.conf.bak vim httpd.conf可以在普通模式下搜索Listen关键字 :/Listen按n键继续向后搜索 在/etc/httpd/conf.d中新建子配置文件port.conf&#xff1a; touch /etc…

观成科技:蔓灵花组织加密通信研究分析总结

1.概述 蔓灵花&#xff0c;又名"Bitter"&#xff0c;常对南亚周边及孟加拉湾海域的相关国家发起网络攻击&#xff0c;主要针对巴基斯坦和中国两国。其攻击目标主要包括政府部门、核工业、能源、国防、军工、船舶工业、航空工业以及海运等行业&#xff0c;其主要意图…

后端每日一题 2:DNS 解析过程

本文首发于公众号&#xff1a;腐烂的橘子 本文梗概&#xff1a; DNS 是什么&#xff0c;有什么作用一条 DNS 记录是什么样的DNS 域名解析原理DNS 服务器如何抵御攻击 DNS 是什么&#xff0c;有什么作用 DNS&#xff08;Domain Name System&#xff09;是一种应用层协议&…

使用和配置:超秀的 MySQL 客户端工具 MyCli

1.安装一个更人性化的一个mysql客户端、终端: sudo apt install mycli 登录方式 mycli -uroot password 2. 功能&#xff1a;界面更好看&#xff0c;且支持自动补全&#xff0c;按tab可以补全 3.mycli使用帮助说明文档 mycli --help用法: mycli [OPTIONS] [DATABASE]例如:…

西门子程序专业备份软件BUDdy for S7和使用说明

西门子程序专业备份软件BUDdy for S7和使用说明

虹科Pico汽车示波器 | 免拆诊断案例 | 2006 款林肯领航员车发动机怠速抖动

故障现象 一辆2006款林肯领航员车&#xff0c;搭载5.4 L发动机&#xff0c;累计行驶里程约为26万km。该车因发动机怠速抖动故障进厂维修&#xff0c;维修人员更换了火花塞、点火线圈及凸轮轴位置传感器&#xff0c;清洗了积炭和喷油器&#xff0c;故障依旧&#xff0c;于是向笔…

SpringBoot学习之Redis下载安装启动【Windows版本】(三十六)

一、下载Redis for Windows Redis 官方网站没有提供 Windows 版的安装包,但可以通过 GitHub 来下载安装包,下载地址:https://github.com/tporadowski/redis/releases 1、网站提供了安装包和免安装版本,这里我们直接选择下面的免安装版本 2、下载后的压缩包解压以后,如下…

C#基础之结构体

结构体 文章目录 1、概念2、基本语法3、示例4、结构体的使用5、访问修饰符6、结构体的构造函数思考1 描述矩形信息思考2 职业名字释放了技能思考3 小怪兽思考4 多个小怪兽思考5 奥特曼打小怪兽 1、概念 结构体是一种一定义变量类型 它是数据和函数的集合&#xff0c;可以在结…

Entity Framework6 Oracle 官网开发说明

Entity Framework, LINQ and Model-First for the Oracle Database

揭秘被忽视的商业模式:全民拼购助力客户实现日销千万的惊人业绩

今天&#xff0c;我想和大家分享一个颇具潜力的模式与玩法&#xff0c;尽管它在外界看来可能略显陈旧。这个模式曾被忽视&#xff0c;但我的一位客户却巧妙运用&#xff0c;实现了惊人的业绩——日销售额接近五千万&#xff0c;日订单量高达300万单。 值得注意的是&#xff0c;…

将文件导入数据库

#include <stdio.h> #include <sqlite3.h> #include <string.h> int main(int argc, const char *argv[]) { //打开数据库 sqlite3 *db NULL; if(sqlite3_open("./dict.db",&db) ! SQLITE_OK){ printf("sqlite…

Java 提取HTML文件中的文本内容

从 HTML 文件中提取文本内容是数据抓取中的一个常见任务&#xff0c;你可以将提取的文本信息用于编制报告、进行数据分析或其他处理。本文分享如何使用免费 Java API 从HTML 文件中提取文本内容。 安装免费Java库&#xff1a; 要通过Java提取HTML文本&#xff0c;需要用到Free…

QT——简易计算器(从0开始)

目录 一、题目描述&#xff1a; 二、创建工程&#xff1a; 1. ​编辑 2. 3. 4. 默认 5. 6. 7. 8. 默认 9. 创建完成 三、UI界面设计&#xff1a; 1. 添加按钮 1. 2. 按钮界面 3. 按钮绑定快捷键 2. 文本框添加 1. 文本框字体 2. 默认文本 3. 文本对齐方式…

Linux多线程(二) 线程同步 信号量互斥锁读写锁条件变量

多个进程同时访问某些资源时&#xff0c;必须考虑同步问题&#xff0c;以确保任一时刻只有一个进程可以拥有对资源的独占式访问。通常&#xff0c;程序对关键资源的访问代码只是很短的一段&#xff0c;我们称这段代码为关键代码段或者临界区&#xff0c;对进程同步&#xff0c;…

机器人系统开发ros2-基础实践01-学会自定义一个机器人动作aciton实体类

您之前在了解操作教程中了解了action 。与其他通信类型及其各自的接口&#xff08;主题/消息和服务/srv&#xff09;一样&#xff0c;您也可以在包中自定义操作。本教程向您展示如何定义和构建可与您将在下一个教程中编写的action服务器和action 客户端一起使用的操作。 需要理…

UE5 GAS开发P41-43 永久效果,去除永久效果,伤害区域,EnumClass,开始重叠与结束重叠事件

这一部分学习了怎么创建一个伤害性的地形(火焰地形,毒沼泽等都可以用这个方式创建) AuraEffectActor.h // Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "GameplayEffect.h&q…

软件测试(Web自动化测试)(二)

一.Selenium WebDriver的基本应用 &#xff08;一&#xff09;安装浏览器驱动 1.关闭浏览器的自动更新功能 以Windows7&#xff08;64位&#xff09;操作系统为例&#xff0c;讲解如何关闭Chrome浏览器的自动更新。首先按下快捷键“WinR”&#xff0c;打开运行对话框&#x…

【c++】深入剖析与动手实践:C++中Stack与Queue的艺术

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章我们来到STL新的内容&#xff0c;stack和queue 目录 1. stack的介绍与使用函数介绍例题一&#xff1a;最小栈例题二&#xff1a;栈的压入、弹出队列栈的模…

Adobe Photoshop CC 2017无法打开解决方案

Adobe Photoshop CC 2017双击无反应&#xff0c;右键以管理员身份运行也没有反应 解决方案&#xff1a; 事件查看器中查看应用程序的事件 如果找到程序报错事件&#xff0c;网上下载ZXPSignLib-minimal.dll文件替换错误模块路径位置的该文件即可 ZXPSignLib-minimal.dll下载地…