![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
程序员面试那点事儿
互联网大厂校招、社招面试官,多年互联网大厂工作经验,分享校招、社招面试题、职场相关内容,互相交流经验
展开
-
学习导航
02动态规划之完全背包问题原创 2021-01-06 21:59:22 · 70 阅读 · 0 评论 -
02动态规划之完全背包问题
一共有N种物品,每种物品有无限多个,第i(i从1开始)种物品的重量为w[i],价值为v[i]。在总重量不超过背包承载上限W的情况下,能够装入背包的最大价值是多少?完全背包(unbounded knapsack problem)与01背包不同就是每种物品可以有无限多个确定状态最后一步转移方程dp[i][j] = max(dp[i−1][j], dp[i][j−w[i]]+v[i]) // j >= w[i]初始条件和边界条件计算顺序https://blog.csdn.net/qq原创 2020-11-18 08:59:50 · 265 阅读 · 0 评论 -
01 动态规划之背包问题
有????个物品,每个物品有一个体积????,价值????,每个物品只能选一次,问在所选体积不超过????的情况下的最大价值?确定状态最后一步最后一步是选第N个物品,看背包容量是否够,放入或者不放入子问题放入的话 问题转化为 前N-1个物品放入体积不超过m-Wn的最大价值不放入的话 问题为 前N-1个物品放入体积不超过m的最大价值所以确定状态为f(i)(j): 前i个物品的体积不超过j的最大价值。转移方程f(i,j) = Math.Max(f(i-1,j-v)+w,f(i-1,j));原创 2020-11-10 09:00:59 · 74 阅读 · 0 评论 -
股票买卖问题
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例1输入: [2,4,1], k = 2输出: 2解释: 在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。分析解题的关键在于根据状态进行穷举,具体到某一天,看看有哪些状态、再看看每个状态对应有哪原创 2020-09-11 09:01:03 · 217 阅读 · 0 评论 -
特殊数据结构:单调队列
队列中的元素单调递增、或者递减public class MonotonicQueue { Deque<Integer> deque = new LinkedList<>(); void push(int i, int[] nums) { while (!deque.isEmpty() && nums[i] > nums[deque.getLast()]) { deque.pollLast();原创 2020-08-26 09:02:20 · 96 阅读 · 0 评论 -
单调栈栈类型题
单调栈是每次新元素入栈后,栈内的元素都保持有序(单调递增或单调递减)的栈。单调栈主要解决Next Greater Number 问题,问题是:给你一个数组,返回一个等长的数组,对应索引存储着下一个更大元素,如果没有更大的元素,就存 -1。例子解释:给你一个数组 [2,1,2,4,3],你返回数组 [4,2,4,-1,-1]。第一个 2 后面比 2 大的数是 4; 1 后面比 1 大的数是 2;第二个 2 后面比 2 大的数是 4; 4 后面没有比 4 大的数,填 -1;3 后面没有比 3 大的数,填原创 2020-08-25 09:03:26 · 129 阅读 · 0 评论 -
一文学会二分查找及其变体,从此再也写不错二分查找
从猜大猜小中可以找出二分思想的影子。二分查找的递归实现和非递归实现public class BinarySearch { //1 声明一个函数,需要传入数组和要查找的元素两个参数 //2 声明数组的最小值和最大值 //3 while循环查找,并定义循环结束条件 low>high //4 定义计算中间值公示 mid=low+(low+(high-low)&g...原创 2019-06-01 11:47:10 · 240 阅读 · 0 评论 -
插入排序
public class InsertionSort { private InsertionSort(){} public static void sort(Comparable[] arr){ int n = arr.length; for (int i=1;i<n;i++){ /* for (int j=i;j...原创 2019-01-03 21:29:51 · 81 阅读 · 0 评论 -
选择排序算法
第一种,只支持int类型的选择排序算法import java.util.Arrays;/** * 在这里编写类的功能描述 * * @author wangkai * @created 2019/1/3 */public class SelectSort { private SelectSort(){} public static void sort...原创 2019-01-03 11:05:43 · 182 阅读 · 0 评论 -
1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。示例:给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 + 7 = 9所以返回 [0, 1]解决方案:...原创 2019-01-02 19:30:21 · 103 阅读 · 0 评论 -
动态规划解题步骤解析
动态规划问题一般形式就是求最值,动态规划有三个要素重叠子问题。通过备忘录和DP数组来优化穷举过程最优子结构。通过子问题的最值得出原问题的最值状态转移方程。如何正确的穷举的关键,可以通过四步法来确定状态转移方程:明确状态-定义DP table-明确选择-明确base case下面将从两个例子来展开介绍,通过斐波那契数列让你明白什么是重叠子问题,通过凑零钱问题分析如何列出状态转移方程。斐波那契数列暴力法public int fib(int N) { if (N == 1 ||原创 2020-07-14 10:58:20 · 289 阅读 · 0 评论 -
第9章 排序
9.4 简单选择排序 冒泡排序的思想就是不断的交换,通过交换完成最终的排序,和做股票短线操作的人类似。 选择排序的思想就是在排序时找到合适的关键字再做交换,并且只移动一次就完成相应关键字的排序定位工作 9.4.1 简单选择排序算法 简单选择排序法就是通过n-1次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录交换...原创 2018-03-20 10:45:30 · 97 阅读 · 0 评论 -
第7章 图
图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G边的集合 7.1 开场白 全国地图旅游选地点问题 7.2 图的定义 图是顶点的有穷的有穷非空集合和顶点之间边的集合组成,通常为:G(V,E),G是一个图,V是图G中顶点的集合,E是...原创 2018-03-09 11:13:31 · 271 阅读 · 0 评论 -
第6章 树
树是n(n>=0)个结点的有限集 6.2 树的定义 树(Tree)是n(n>=0)个结点的有限集。n=0时为空树。在任意一颗非空树中:(1)有且仅有一个特定的称为根结点(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,,,,其中每一个集合本身又是一颗树,并且称为根的子树 树的结点包含一个数据元素及若干指向其子树的分支...原创 2018-03-09 06:07:26 · 147 阅读 · 0 评论 -
第5章 串
串是由零个或多个字符组成的有限序列,又名叫字符串 5.1 开场白 回文诗: 枯眼望遥山隔水,往来曾见几心知?壶空怕酌一杯酒,笔下难成和韵诗。壶空怕酌一杯酒,笔下难成和韵诗。途路阻人离别九,讯音无雁寄回迟。孤灯夜守长廖寂,夫忆妻兮父忆儿 5.2 串的定义 串中的字符数目n称为串的长度,零个字符的串称为空串 5.3 串的比较 ...原创 2018-03-08 06:24:46 · 152 阅读 · 0 评论 -
第4章 栈与队列
栈是限定仅在表尾进行插入和删除操作的线性表,队列是只需要在一端进行插入操作、而在另一端进行删除操作的线性表Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber){if(stackNumber==1){if(s->top1==-1)return ERRROR;*e=S->data[S->top1--];}el...原创 2018-03-07 15:55:57 · 192 阅读 · 0 评论 -
第3章 线性表
线性表 零个或多个数据元素的有限序列3.1 开场白 幼儿园门口的小孩子排队的组织方式,就是线性表3.2 线性表的定义 线性表 零个或多个数据元素的有限序列 直接前驱元素,直接后继元素 星座是线性表,公司的组织架构就不是线性表,皮包公司可能是,班级里的点名册是线性表演唱会排队的人群是线性表 3.3 线性表的抽象数据类型 ADT 线性表(List)Data...原创 2018-03-06 17:54:22 · 270 阅读 · 0 评论 -
路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。说明: 叶子节点是指没有子节点的节点。示例:给定如下二叉树,以及目标和 sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1返回 true, 因为存在目标和为 22 的根节点到原创 2020-08-10 08:47:42 · 74 阅读 · 0 评论 -
N皇后问题
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。上图为 8 皇后问题的一种解法。给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。示例:输入: 4输出: [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q",原创 2020-08-08 14:29:35 · 137 阅读 · 0 评论 -
全排列问题
给定一个 没有重复 数字的序列,返回其所有可能的全排列。示例:输入: [1,2,3]输出:[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]public class Solution1 { List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>>原创 2020-08-08 10:29:11 · 147 阅读 · 0 评论 -
回溯算法总结
回溯问题,本质就是决策树的遍历过程,纯暴力穷举,复杂度一般都很高。从一条路往前走,能进则进,不能进的时候就退回来,尝试另外一条路。写backtrack算法时,需要维护走过的路径和当前可以做出的选择列表,当触发结束条件时,将路径记入结果集。backtrace(路径、选择列表){ if(符合条件){ 添加到结果中 } for(选择列表){ 做选择 backtrace(路径、选择列表); 撤销选择 }}全排列问题N皇后问题..原创 2020-08-08 14:50:01 · 144 阅读 · 0 评论 -
删除重复的元素
移除元素给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。示例1:给定 nums = [3,2,2,3], val = 3,函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。示例 2:给定 nums = [0,1,2,2,原创 2020-08-07 10:11:18 · 1014 阅读 · 0 评论 -
和可被 K 整除的子数组
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。输入:A = [4,5,0,-2,-3,1], K = 5输出:7解释:有 7 个子数组满足其元素之和可被 K = 5 整除:[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]和 和为 K 的子数组 题目相似,不同的是计算key的时候,这个计算公式为int key = (pre % K + K) % K;原创 2020-08-06 09:24:04 · 152 阅读 · 0 评论 -
路径总和 III
给定一个二叉树,它的每个结点都存放着一个整数值。找出路径和等于给定数值的路径总数。路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。示例:root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 10 / \ 5 -3 / \ \ 3 2 11 / \原创 2020-08-06 08:56:06 · 84 阅读 · 0 评论 -
字符串乘法问题总结
公式模版for(num1){ for(num2){ res[i + j + 1] = sum % 10; res[i + j] = res[i + j] + sum / 10; }}问题分析数组承载计算结果计算结果落在数组中i+j和i+j+1的位置 public String multiply(String num1, String num2) { if (num1.equals("0") || num2.equals("0")) {原创 2020-08-05 18:57:58 · 162 阅读 · 0 评论 -
链表之虚结点
https://www.cnblogs.com/waring/p/4538042.html当对一个链表的操作会改变头指针时,可以增加一个虚拟结点放在头结点前,当链表操作结束时再删除,这样可以减少一些不必要的判断,使代码更简洁更有可读性。例如,在删除一个给定值的结点时,这个结点可能会在链表中间,也可能是头结点,当是头结点时就需要修改链表表头指针,而添加一个虚拟结点后就不需要关系删除的是头结点还是中间结点了。ListNode* removeElements(ListNode* head, int val)原创 2020-08-04 09:08:47 · 1239 阅读 · 1 评论 -
一文搞懂leetcode加法运算
运算公式sum=x+y+carry;current=sum%10;carry=sum/10;原创 2020-08-04 10:27:45 · 394 阅读 · 0 评论 -
递归理解
首先,要理解递归,不要去在脑子里想这个递归过程,因为很容易绕进去。理解递归递归定义是自己调用自己。举个例子,比如去电影院,你女朋友问你这是第几排,你问前一排人,前一排人也不知道,就再问前一个人,知道第一排,然后再一排一排的传回来,去问的过程是递,回来的过程是归,总结成代码就是public int f(int n){ if (n==1){ return 1; } return f(n-1)+1;}递归二要素大问题可以分解原创 2020-08-06 08:15:13 · 105 阅读 · 0 评论 -
红黑树
变换规则:旋转和颜色变换规则:所有插入的点默认为红色变颜色的情况:当节点的父亲是红色,且它的祖父节点的另一个子节点(叔叔节点)也是红色1 把父节点设为黑色2 把叔叔节点设为黑色3 把祖父也就是父亲的父亲设为红色...原创 2020-03-12 11:40:27 · 86 阅读 · 0 评论 -
前缀和
什么是前缀和什么是差分和为 K 的子数组和可被 K 整除的子数组统计[优美子数组]每个元音包含偶数次的最长子字符串路径总和 III原创 2020-07-27 10:07:12 · 81 阅读 · 0 评论 -
二叉树前、中、后、层序遍历详解
树是什么二叉树是什么二叉树的存储结构二叉树的遍历原创 2020-07-15 15:27:00 · 428 阅读 · 0 评论 -
以跳跃游戏分析存在性动态规划问题
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个位置。确定状态最后一步分析题意可以知,跳到的是最后一步,那么最后一步的前一步有可能是前一步到最后一步的前一步的中间范围,要想跳到最后一步需要满足两个条件:能跳到第i块位置ai+i>=j(要跳到的位置)子问题子问题就是是否能跳到第i块位置状态转移方程状态转移方程为f(j)=f(i) AND i+ai>j初始条件和边界条件初始条件 f(0)=true原创 2020-07-14 12:03:52 · 169 阅读 · 0 评论 -
以凑硬币问题分析动态规划最值类解题步骤
给定不同面值的硬币coins和一个总金额amount,编写一个函数来计算可以凑成总金额所需的最小硬币个数。如果没有任何一种硬币组合能组成总金额,返回-1。首先根据最小两个字和题意可以分析是用动态规划来进行解题。确定状态解题的前提就是确定题中的状态是什么,一般情况下,动态规划需要开一个数组,数据的每个元素f(i)或者f(i)(j)代表的就是状态。确定状态需要通过两个思考:最后一步和子问题,找出原问题和子问题中变化的变量,这个变量就是要确定的状态。最后一步例如凑硬币问题中,可选硬币金额是2,5,7,原创 2020-07-14 10:43:49 · 661 阅读 · 0 评论 -
以不同路径问题分析动态规划计数类解题步骤
一个机器人位于一个m*n网络的左上角,机器人每次只能向左向右移动一步。机器人试图达到网格的右下角,总共有多少条不同的路径。首先要确定状态确定状态最后一步这里的最后一步是走到网格的右下角,那么定义走到最后一个位置的路径数是f(i)(j),走到这一步只有两种可能,从上边来,或者从左边来。子问题从上边来为f(i-1)(j),从左边来为f(i)(j-1),这两个都转化为了子问题。状态转移方程从上面可知转移方程为f(i)(j)=f(i-1)(j)+f(i)(j-1);初始条件和边界条件首先从左上原创 2020-07-14 10:42:25 · 240 阅读 · 0 评论 -
滑动窗口算法总结
滑动窗口算法一般需要用到双指针来进行解决,另外一类需要用到特殊的数据结构如Map,队列等。核心在于如何控制窗口的移动,左右指针什么时候动,什么时候不动,这个是关键。最小覆盖子串给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。示例:输入: S = "ADOBECODEBANC", T = "ABC"输出: "BANC"说明:如果 S 中不存这样的子串,则返回空字符串 “”。如果 S 中存在这样的子串,我们保证它是唯一的答案。思路:首先在S串上原创 2020-06-23 07:38:33 · 788 阅读 · 0 评论 -
Bellman-Ford单源最短路径
如果一个图没有负权环,从一个点到另外一个点最多V个顶点,有V-1条边,否则某个顶点经过2次,存在负权环原创 2020-04-26 16:19:19 · 90 阅读 · 0 评论 -
Dijkstra单源最短路径算法
图中不能有负权边复杂度O(E log(V))原创 2020-04-26 14:43:20 · 150 阅读 · 0 评论 -
String和Long源码解析
String不变性public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[];...原创 2020-04-14 15:59:14 · 301 阅读 · 0 评论 -
堆的实现方式和堆排序
理解堆堆是一个完全二叉树堆中的每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值存储:由于堆是一种完全二叉树,完全二叉树比较适合用数组来存储堆化:插入和删除堆中元素之后,需要重新调整,让其满足堆特性的过程往堆中插入一个元素(从下往上堆化)删除堆中的一个元素(从上往下堆化)堆排序建堆有两种建堆方式,一种是利用一个空堆,不断插入。另外一种是从第一个非叶子...原创 2020-04-13 08:00:04 · 204 阅读 · 0 评论 -
哈希算法
是什么将任意长度的二进制串映射为固定长度的二进制串。要求从哈希值不能反向推导出原始数据对输入数据非常敏感,哪怕原始数据只修改了一个Bit,最后得到的哈希值也大不相同散列冲突概率要小,不同的原始数据,哈希值冲突的概率要小哈希算法的执行效率要高,针对很长的文本,也要很快计算出哈希值应用安全加密唯一标识数据校验散列函数负载均衡数据分片(关键词次数、判断图片是否在图库中)...原创 2020-04-07 15:48:22 · 96 阅读 · 0 评论