数据结构与算法 经典题库练习

文章目录

    • 一、字符串、时间复杂度与逻辑思维训练
        • 1、Z字形变换
        • 2、字符串转换整数(atoi)
        • 3、字符流中第一个不重复的字符
        • 4、小易的英语软件
    • 二、指针、数组、链表组合练习
        • 5、盛最多水的容器
        • 6、删除链表的倒数第N个节点
        • 7、最小覆盖子串
        • 8、数组中相加和为0的三元组
        • 9、矩阵
        • 10、shopee的链表笔试题
        • 11、顺时针打印矩阵
    • 三、二分法
        • 12、机器人跳跃问题
        • 13、百度春招笔试题
        • 14、旋转数组的最小数字
    • 四、泛型
        • 15、泛型
    • 五、二叉树、深度优先搜索
        • 16、验证二叉搜索树
        • 17、二叉树的最大深度
        • 18、二叉树加强训练
    • 六、堆、栈、列表
        • 19、最小栈
        • 20、栈的压入弹出序列
        • 21、有序矩阵中的第K小的元素
        • 22、小米笔试题——栈
    • 七、递归、回溯、贪心算法
        • 23、两数相加
        • 24、字符串的排列
        • 25、剪绳子
    • 八、动态规划
        • 26、篮球队
        • 27、最长回文子串
        • 28、动态规划经典例题
        • 29、字节跳动笔试题-动态规划

一、字符串、时间复杂度与逻辑思维训练

1、Z字形变换

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:

L   C   I   R
E T O E S I I G
E   D   H   N

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L     D     R
E   O E   I I
E C   I H   N
T     S     G

考察点:字符串、时间复杂度、逻辑思维

2、字符串转换整数(atoi)

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:

如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0 。

提示:
本题中的空白字符只包括空格字符 ’ ’ 。
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:
输入: "42"
输出: 42

示例 2:
输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:
输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

示例 4:
输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
     因此无法执行有效的转换。

示例 5:
输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 
     因此返回 INT_MIN (−231) 。

考察点:字符串、时间复杂度、数学逻辑思维

3、字符流中第一个不重复的字符

请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

解法:使用map实现

进阶:使用哈希+队列实现

考察点:哈希表、字符串

4、小易的英语软件

小易是班级的英语课代表, 他开发了一款软件开处理他的工作。
小易的软件有一个神奇的功能,能够通过一个百分数来反应你的成绩在班上的位置。“成绩超过班级 …% 的同学”。
设这个百分数为 p,考了 s 分,则可以通过以下式子计算得出 p:
p = ( 分数不超过 s 的人数 - 1) 班级总人数
突然一天的英语考试之后,软件突然罢工了,这可忙坏了小易。成绩输入这些对于字写得又快又好的小易当然没有问题,但是计算这些百分数……这庞大的数据量吓坏了他。
于是他来找到你,希望他编一个程序模拟这个软件:给出班级人数 n,以及每个人的成绩,请求出某几位同学的百分数。

第一行一个整数 n,表示班级人数。
第二行共 n 个自然数,第 i 个数表示第 i 位同学的成绩 a_i。
第三行一个整数 q,表示询问的次数。
接下来 q 行,每行一个数 x,表示询问第 x 位同学的百分数。

输出应有 q 行,每行一个百分数,对应每一次的询问。
为了方便,不需要输出百分号,只需要输出百分号前的数字即可。四舍五入保留六位小数即可。

输入例子1:
3
100 98 87
3
1
2
3

输出例子1:
66.666667
33.333333
0.000000

考察点:网易2020校招笔试题、数学逻辑思维

二、指针、数组、链表组合练习

5、盛最多水的容器

给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

数据结构与算法 经典题库练习_第1张图片

示例:
输入:[1,8,6,2,5,4,8,3,7]
输出:49

考察点:双指针、数组

6、删除链表的倒数第N个节点

  • 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

​ 说明:给定的 n 保证是有效的。

  • 难度提升
    使用一趟扫描实现。

考察点:链表、双指针

7、最小覆盖子串

给你一个字符串 S、一个字符串 T 。请你设计一种算法,可以在 O(n) 的时间复杂度内,从字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:
输入:S = "ADOBECODEBANC", T = "ABC"
输出:"BANC"

提示:
如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

考点:暴力解析
提升:滑动窗口(集合思维)

考察点:哈希表、双指针、字符串、Sliding Window

8、数组中相加和为0的三元组

给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。
注意:
三元组(a、b、c)中的元素必须按非降序排列。(即a≤b≤c)

解集中不能包含重复的三元组。

例如,给定的数组 S = {-1 0 1 2 -1 -4},解集为(-1, 0, 1) (-1, -1, 2)

考察点:数组、双指针

9、矩阵

小易有一个体积巨大的货物,具体来说,是个在二维平面上占地cd的货物。
小易有一个n
m的广场,想把货物放在这个广场上。不幸的是,广场上已经有了一些障碍物,障碍物所在的格子不能放置你的货物。小易现在想知道能否成功地放置货物。

第一行数字t,表示有t组数据。
对于每一组数据,第一行三个数字n,m,k,表示广场的大小和障碍物的个数。接下来k行,每行两个数x,y,表示一个障碍物的坐标。
接下来一行两个数c,d,表示货物的大小。
1<=n,m<=1000,1<=c<=n,1<=d<=m,0<=k<=n*m

对于每组数据,输出"YES"或者"NO"表示货物是否可以被放置。

输入例子1:
2
3 3 1
1 1
2 2
3 3 1  
2 2  
2 2  

输出例子1:
YES
NO

考察点:网易2020校招笔试题、深度优先搜索、广度优先搜索、数组

10、shopee的链表笔试题

1.输入一个链表,反转链表后,输出新链表的表头

2.判断给定的链表中是否有环

考察点:链表、双指针

11、顺时针打印矩阵

实现方法:
    public ArrayList<Integer> printMatrix(int [][] matrix)
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

考察点:数组

※强化:时间复杂度O(n)或空间复杂度O(1)

三、二分法

12、机器人跳跃问题

机器人正在玩一个古老的基于DOS的游戏。游戏中有N+1座建筑——从0到N编号,从左到右排列。编号为0的建筑高度为0个单位,编号为i的建筑的高度为H(i)个单位。

起初, 机器人在编号为0的建筑处。每一步,它跳到下一个(右边)建筑。假设机器人在第k个建筑,且它现在的能量值是E, 下一步它将跳到第k+1个建筑。它将会得到或者失去正比于与H(k+1)与E之差的能量。如果 H(k+1) > E 那么机器人就失去 H(k+1) - E 的能量值,否则它将得到 E - H(k+1) 的能量值。

游戏目标是到达第个N建筑,在这个过程中,能量值不能为负数个单位。现在的问题是机器人以多少能量值开始游戏,才可以保证成功完成游戏?

输入描述:
第一行输入,表示一共有 N 组数据.

第二个是 N 个空格分隔的整数,H1, H2, H3, …, Hn 代表建筑物的高度

输出描述:
输出一个单独的数表示完成游戏所需的最少单位的初始能量

输入例子1:
5
3 4 3 2 4

输出例子1:
4

输入例子2:
3
4 4 4

输出例子2:
4

输入例子3:
3
1 6 4

输出例子3:
3

考察点:二分法、数学方法、逆推法

13、百度春招笔试题

  • 请实现有重复数字的有序数组的二分查找。
    输出在数组中第一个大于等于查找值的位置,如果数组中不存在这样的数,则输出数组长度加一
示例1:
输入
5,4,[1,2,4,4,5]
输出
3

方法:二分查找

实现:    /**
     * 二分查找
     * @param n int整型 数组长度
     * @param v int整型 查找值
     * @param a int整型一维数组 有序数组
     * @return int整型
     */
    public int upper_bound_ (int n, int v, int[] a) {}
  • 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
    输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
    例如数组[3,4,5,1,2]为[1,2,3,4,5]的一个旋转,该数组的最小值为1。
    NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

    实现:
    public int minNumberInRotateArray(int [] array){}

考察点:二分查找、数组

14、旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。

例如数组[3,4,5,1,2]为[1,2,3,4,5]的一个旋转,该数组的最小值为1。

NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

考察点:二分查找

四、泛型

15、泛型

使用泛型编写程序,使用ArrayList和LinkedList。
首先创建一个包含Integer实例对象的数组表ArrayList,依次往里面添加1,2,3,1,3这几个整型对象后,将其打印出来,然后将第4、5个对象进行更改,更改为4和5这两个整型对象,然后用Iterator接口将ArrayList中的元素全部打印出来;最后在ArrayList中在创建LinkedList,将第0,3位置的插入整型对象元素10和30,然后用Iterator接口遍历LinkedList中的各元素,将值小于4的元素输出后输出LinkedList中的各元素。

考察点:泛型、逻辑思维

五、二叉树、深度优先搜索

16、验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:
输入:
    2
   / \
  1   3
输出: true

示例 2:
输入:
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4 。

考察点:树、深度优先搜索、递归

17、二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7],
它的最大深度为3 。

方法一:递归

方法二:BFS(广度优先搜索)
提示:队列

方法三:DFS(深度优先搜索)
提示:栈

考察点:树、深度优先搜索

18、二叉树加强训练

  • 二叉树的镜像

    实现方法:
        public void Mirror(TreeNode root)
    

    操作给定的二叉树,将其变换为源二叉树的镜像。
    输入描述:

二叉树的镜像定义:
         源二叉树 :
    	    8
    	   /  \
    	  6   10
    	 / \   / \
    	5   7 9  11
    	
    		镜像二叉树:
                8
              /   \
             10    6
            / \    / \
            11 9   7  5
  • 树的子结构

    实现方法:
        public boolean HasSubtree(TreeNode root1,TreeNode root2)
    

    输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

    B是A的子结构, 即 A中有出现和B相同的结构和节点值。

    例如:
    给定的树 A:
    
        3
       / \
      4   5
     / \
    1   2
    
    给定的树 B:
       4 
      /
     1
    返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
    
    示例 1:
    输入:A = [1,2,3], B = [3,1]
    输出:false
    示例 2:
    
    输入:A = [3,4,5,1,2], B = [4,1]
    输出:true
    
    限制:
    0 <= 节点个数 <= 10000
    

考察点:二叉树

六、堆、栈、列表

19、最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

示例:
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

提示:
pop、top 和 getMin 操作总是在 非空栈 上调用。

考察点:栈、设计

20、栈的压入弹出序列

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

考察点:栈、时间复杂度、贪心算法

21、有序矩阵中的第K小的元素

给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。

示例:

matrix = [
   [ 1,   5,    9],
   [10, 11, 13],
   [12, 13, 15]
]

k = 8,返回 13

解法:暴力解析(二维合并为一维)

进阶:二分查找

提升:归并排序

考察点:堆、二分查找

22、小米笔试题——栈

  • 给出一个仅包含字符’(’,’)’,’{’,’}’,’[‘和’]’,的字符串,判断给出的字符串是否是合法的括号序列
    括号必须以正确的顺序关闭,"()“和”()[]{}“都是合法的括号序列,但”(]“和”([)]"不合法。
示例1
输入
"["
输出
false

示例2
输入
"[]"
输出
true

考点:栈、字符串

  • 给你一个1->n的排列和一个栈,入栈顺序给定
    你要在不打乱入栈顺序的情况下,对数组进行从大到小排序
    当无法完全排序时,请输出字典序最大的出栈序列
输入
[2,1,5,3,4]
输出
[5,4,3,1,2]

说明
2入栈;1入栈;5入栈;5出栈;3入栈;4入栈;4出栈;3出栈;1出栈;2出栈

备注:
n<=1e6

考点:栈、排序

七、递归、回溯、贪心算法

23、两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

可以假设除了数字 0 之外,这两个数都不会以 0 开头。

数据结构与算法 经典题库练习_第2张图片

示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

考察点:递归、链表、数学方法

24、字符串的排列

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

提示:输出字符串不能重复

考察点:字符串、递归、回溯

25、剪绳子

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
输出描述:
输出答案。

示例:输入8    输出18

方法一:递归
方法二:动态规划
方法三:贪婪解法

考察点:贪心 数组 数量关系 高级算法 组合数学

八、动态规划

26、篮球队

小Q是篮球训练队的教练,篮球队新加入了N名队员,第i名队员的篮球水平值为Ai。
小Q现在要把他们按照以下的要求分为A队和B队进行训练:
1、A队的队员水平值之和严格大于B队的队员水平值之和
2、对于A队中的任意一名队员,如果把他分配到B队,A队的水平值之和就会严格小于B队的水平值之和。
3、每个队员必须要加入一个队伍
小Q现在想知道有多少种方案可以按照以上要求完成分队。

输入描述:
输入包括两行, 输入的第一行为一个正整数n(2 <= N <= 50), 表示队员的数量。
第二行包括N个正整数 Ai(1 <= Ai<= 6 x 10^4), 表示每名队员的篮球水平值, 以空格分割。

输出描述:
输出一个正整数, 表示方案数。

示例1

输入
4
5 4 7 6

输出
2

考察点:动态规划

27、最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:

输入: "cbbd"
输出: "bb"

解法:暴力解析

提升:动态规划

考察点:哈希表、字符串、动态规划

28、动态规划经典例题

  • 连续子数组的最大和:

    HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?

    例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
    
  • 买卖股票的最佳时机问题整合:

  • 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
    设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
    注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

示例 2:
输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

示例 3:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

提示:
1 <= prices.length <= 3 * 10 ^ 4
0 <= prices[i] <= 10 ^ 4

考察点:动态规划(可选择暴力搜索、贪心算法)

  • 给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。
    你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
    返回获得利润的最大值。
    注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易只需要为支付一次手续费。
示例 1:
输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8
解释: 能够达到的最大利润:  
在此处买入 prices[0] = 1
在此处卖出 prices[3] = 8
在此处买入 prices[4] = 4
在此处卖出 prices[5] = 9
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

注意:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.

考察点:动态规划

  • 给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
    设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
    你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
    卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
示例:
输入: [1,2,3,0,2]
输出: 3 
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]

考察点:动态规划

  • 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
    设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
    注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: [3,3,5,0,0,3,1,4]
输出: 6
解释: 在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
     随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。

示例 2:
输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。   
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。   
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

示例 3:
输入: [7,6,4,3,1] 
输出: 0 
解释: 在这个情况下, 没有交易完成, 所以最大利润为 0。

考察点:动态规划

  • 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
    设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
    注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: [2,4,1], k = 2
输出: 2
解释: 在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。

示例 2:
输入: [3,2,6,5,0,3], k = 2
输出: 7
解释: 在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。
     随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。

考点:动态规划(可考虑递归)

29、字节跳动笔试题-动态规划

假设你有一个数组,其中第 i 个元素是股票在第 i 天的价格。
你有一次买入和卖出的机会。(只有买入了股票以后才能卖出)。
请你设计一个算法来计算可以获得的最大收益。

示例1
输入
[1,4,2]
输出
3

示例2
输入
[2,4,1]
输出
2

实现:
public int maxProfit (int[] prices){}

考察点:动态规划 数组

你可能感兴趣的:(数据结构与算法,java,数据结构,算法)