
编程练习
文章平均质量分 78
Java语言编程练习
子木_98
这个作者很懒,什么都没留下…
展开
-
【JZ-68-II】二叉树的最近公共祖先(深度优先遍历、递归)
目录题目算法思路具体代码复杂度分析参考题目算法思路与【JZ-68-I】的区别在于二叉树不再是二叉搜索树了,也就是说我们无法利用节点的值的大小关系来判断节点的位置关系了,可以采用 深度优先遍历。递归终止条件:越过了叶节点:直接返回 nullnullnullrootrootroot 等于p、q:返回 rootrootroot递推过程:开启左子节点的递归,返回值记为 leftleftleft开启右子节点的递归,返回值记为 rightrightright返回值(情况1.可以合并到3.和原创 2021-03-29 23:15:25 · 191 阅读 · 0 评论 -
【JZ-68-I】二叉搜索树的最近公共祖先(树)
目录题目算法思路方法一-迭代方法二-递归参考题目算法思路所谓的 【最近公共祖先】,也就是说 rootrootroot 是节点 ppp 和 qqq 的公共祖先,且 root.leftroot.leftroot.left 、 root.rightroot.rightroot.right 都不是节点 ppp 和 qqq 的公共祖先,可能的位置关系为:ppp 和 qqq 分别位于 rootrootroot 的左右子树中;p=rootp=rootp=root,且 qqq 位于 rootrootroot原创 2021-03-29 18:19:07 · 245 阅读 · 0 评论 -
【JZ-67】把字符串转换成整数(数学、字符串)
目录题目算法思路具体代码复杂度分析代码优化参考题目算法思路本问题的几个关键点:符号位:可能为“+”、“-”,也可能没有,可以新建一个变量保存符号位。字符转数字:用该字符的ASCII码减去“0”的ASCII码即可得到该字符对应的数字。数字拼接:从左向右遍历数字,设当前数字为 xxx,数字结果为 resresres,则数字拼接递推公式为res=10×res+xres=10\times res+xres=10×res+x数字越界处理:每一轮数字拼接之前,先判断 resresres 在拼接后是原创 2021-03-29 17:33:43 · 210 阅读 · 0 评论 -
【JZ-66】构建乘积数组(找规律)
目录题目算法思路具体代码复杂度分析参考题目算法思路显然B[i]=A[0]×A[1]×...×A[i−1]×A[i+1]×...×A[n−1]×A[n]B[i]=A[0]\times A[1]\times ... \times A[i-1]\times A[i+1]\times ... \times A[n-1]\times A[n]B[i]=A[0]×A[1]×...×A[i−1]×A[i+1]×...×A[n−1]×A[n],也就是说结果集中任意一个元素 = 其左边所有元素的乘积 * 其右边所有元原创 2021-03-28 22:43:53 · 115 阅读 · 0 评论 -
【JZ-65】不用加减乘除做加法(位运算)
目录题目算法思路具体代码复杂度分析参考题目算法思路不用加减乘除的加法运算 = 不进位加法 + 进位 = 异或运算 + 与运算后左移一位,即,和 s = 无进位和 n + 进位 c例如,a = 12, b = 10 时:a(i)b(i)无进位和 n(i)进位 c(i+1)0000011010101101最终结果为 22, 即 10110循环求无进位和 n 和进位 c,直到进位 c = 0,此时的和 s = n,返回 n由于原创 2021-03-28 21:00:38 · 257 阅读 · 0 评论 -
【JZ-64】求 1 + 2 + ... + n(递归、脑筋急转弯)
目录题目算法思路具体代码复杂度分析参考题目算法思路题设要求不能使用乘除法,所以(1+n)×n/2(1+n)\times n /2(1+n)×n/2平均计算方法不可以用;要求不能使用while、for、if 等关键字以及条件判断语句,所以迭代法也不可以用。至于递归法,最容易想到的递归代码如下:class Solution { public int sumNums(int n) { if(n == 1)return 1; n += sumNums(n - 1)原创 2021-03-28 20:12:10 · 274 阅读 · 0 评论 -
【JZ-63】股票的最大利润(动态规划)
目录题目算法思路具体代码复杂度分析参考题目算法思路该问题也就是要找出给定数组中两个数字之间的最大差值,且第二个数字必须大于第一个数字。如果用暴力法求解,时间复杂度为 O(n2)O(n^2)O(n2),会超时。利用 动态规划 思想通过一次遍历就可以解决该问题。设 dp[i]dp[i]dp[i] 代表以 prices[i]prices[i]prices[i] 为结尾的子数组的最大利润,用一个变量 minPriceminPriceminPrice 记录目前为止最低价格,则 dp[i]=max(dp[原创 2021-03-27 23:38:35 · 184 阅读 · 0 评论 -
【JZ-62】圆圈中最后剩下的数字(动态规划)
目录题目算法思路具体代码复杂度分析参考题目算法思路模拟整个删除过程,即需要循环删除 n - 1 轮,每一轮中遍历链表寻找待删除的节点需要 m 次访问操作,故总的时间复杂度会高达 O(mn)O(mn)O(mn),按照题设中给出的m、n的取值范围很显然会超时。本题为 【约瑟夫环】 问题,可以用 动态规划 解决。设原问题为 【n,m问题】,数字环为 0, 1, 2,…, n - 1 ,解为 f(n)f(n)f(n);【n - 1,m问题】:数字环为 0, 1, 2,…, n - 2,解为 f(n−1原创 2021-03-27 21:31:30 · 169 阅读 · 0 评论 -
【JZ-61】扑克牌中的顺子(哈希表、排序)
目录题目算法思路方法一-集合+遍历方法二-排序+遍历参考题目算法思路5张牌为顺子的充要条件为:除大小王外,没有重复数字;除大小王外,最大数-最小数<5注意这里最大最小数的差值并不一定为4,当有大小王时可能小于4,例如[0,0,3,4,5]是一个顺子,但最大最小数差值为2方法一-集合+遍历class Solution { public boolean isStraight(int[] nums) { Set<Integer> repeat = n原创 2021-03-27 11:31:14 · 708 阅读 · 0 评论 -
【JZ-60】n 个骰子的点数(动态规划)
题目算法思路设 n 枚骰子点数和为 x 的概率为 f(n,x)f(n,x)f(n,x),输入 n 个骰子的点数和概率列表为 f(n)f(n)f(n)。显然有递推公式:f(n,x)=∑i=16f(n−1,x−i)×16f(n,x)=\sum_{i=1}^6f(n-1,x-i)\times \frac{1}{6}f(n,x)=i=1∑6f(n−1,x−i)×61需要注意的是这样递推的话, f(n−1,x−i)f(n-1,x-i)f(n−1,x−i) 存在 边界问题,例如 n = x = 2 ,即计算原创 2021-03-27 10:54:20 · 193 阅读 · 0 评论 -
【JZ-59-II】队列的最大值(单调队列)
目录题目算法思路具体代码复杂度分析参考题目算法思路“空间换时间”,构建一个递减列表来保存队列内元素,使得队列最大元素始终位于列表首位,显然需要使用 双向队列。当执行入队操作时:若队列内存在小于该元素 xxx 的数字,则应将 双向队列尾部 所有小于 xxx 的元素弹出;当执行出队操作时:若出队的元素时队列内的最大元素,则应将 双向队列首元素 出队,保持其与队列内元素的一致性。具体函数设计:获取最大值max_value():若deque为空,返回 -1;否则返回deque首元素。入队p原创 2021-03-25 23:17:12 · 204 阅读 · 0 评论 -
【JZ-59-I】滑动窗口的最大值(队列)
目录题目方法一-暴力求解具体代码复杂度分析方法二-队列算法思路具体代码复杂度分析参考题目方法一-暴力求解遍历数组具体代码class Solution { public int[] maxSlidingWindow(int[] nums, int k) { if(nums.length == 0)return new int[0]; int[] res = new int[nums.length - k + 1]; for(int i = 0原创 2021-03-24 22:41:28 · 276 阅读 · 0 评论 -
【JZ-58-II】左旋转字符串(字符串)
目录题目方法一-字符串切片算法思路具体代码复杂度分析方法二-列表遍历拼接算法思路具体代码复杂度分析方法三-字符串遍历拼接算法思路具体代码复杂度分析参考题目方法一-字符串切片算法思路直接使用字符串切片函数获得 s[0 : n - 1] 和 s[n : ]然后将两者拼接起来具体代码class Solution { public String reverseLeftWords(String s, int n) { String res1 = s.substring(n);原创 2021-03-24 17:16:33 · 268 阅读 · 0 评论 -
【JZ-58-I】翻转单词顺序(字符串、双指针)
目录题目算法思路具体代码复杂度分析参考题目算法思路倒序 遍历字符串,用 双指针 记录每个单词的左右边界。具体代码class Solution { public String reverseWords(String s) { s = s.trim();//删除首尾空格 int j = s.length() - 1, i = j; StringBuilder res = new StringBuilder(); //从后往前遍历原创 2021-03-24 17:16:21 · 85 阅读 · 0 评论 -
【JZ-57-II】和为 s 的连续正数序列(数学、滑动窗口)
目录题目方法一-求和公式算法思路具体代码复杂度分析方法二-滑动窗口(双指针)算法思路具体代码复杂度分析题目参考方法一-求和公式算法思路设该序列的左右边界分别为 iii 和 jjj ,则序列元素和等于平均值乘以元素个数,即:target=(i+j)×(j−i+1)2target=\frac{(i+j)\times(j-i+1)}{2}target=2(i+j)×(j−i+1),可以由此推出右边界 jjj 的计算公式(右边界恒大于左边界,舍去负数解),即:j=−1+1+4(i2−i+2×target原创 2021-03-24 00:16:25 · 276 阅读 · 0 评论 -
【JZ-57】和为 s 的两个数字(双指针)
目录题目算法思路具体代码复杂度分析题目参考算法思路对撞双指针,即两个指针分别从数组的两端开始向中间移动具体代码注意:题设中限制了数组中的数字在1至10^6之间,所以nums[i] + nums[j]不会越界,如果没有限制上限的话可以改为比较target - nums[i]与nums[j]的大小关系,若数字可能为负数的话,可以直接用 long 去比较,就好比二分查找时最好用left + ((right - left) >> 1)而不是(left + right) / 2class S原创 2021-03-23 23:04:02 · 107 阅读 · 0 评论 -
【JZ-56-II】数组中数字出现的次数 II(哈希表、位运算、状态机)
题目原创 2021-03-23 16:38:58 · 428 阅读 · 0 评论 -
【JZ-56-I】数组中数字出现的次数(位运算)
目录题目算法思路具体代码复杂度分析其他题目参考算法思路首先考虑,如果整型数组内除了一个数字以外其他数字都出现了两次,那么 对所有数字进行异或操作 ,得到的结果就是只出现了一次的那个数字。现在的问题是有两个只出现一次的数字,不难想到将所有数字分为两组,使得 相同的数字分在同一个组,并且那两个 只出现了一次的数字被分在不同的组,那么分别对两个组进行异或操作,就可以得到要找的两个数字。那么问题的关键就在于如何实现这样的分组,假设这两个只出现了一次的数字为 aaa 和 bbb,那么所有数字的异或结果 =原创 2021-03-22 23:05:35 · 150 阅读 · 0 评论 -
【JZ-55-II】平衡二叉树(DFS)
目录题目方法一-前序遍历(从顶至底判断)算法思路具体代码复杂度分析方法二-后序遍历(从底至顶判断)算法思路具体代码复杂度分析题目参考方法一-前序遍历(从顶至底判断)算法思路通过比较某子树的左右子树的深度差来判断该子树是否平衡,若所有子树都平衡,则此树平衡。用【JZ-55-I】中的方法获取树的深度。具体代码/** * Definition for a binary tree node. * public class TreeNode { * int val; * Tree原创 2021-03-22 17:59:04 · 195 阅读 · 0 评论 -
【JZ-55-I】二叉树的深度(DFS、BFS)
目录题目方法一-递归(DFS)算法思路具体代码复杂度分析方法二-广度优先遍历-I算法思路具体代码复杂度分析方法三-广度优先遍历-II算法思路具体代码复杂度分析题目参考方法一-递归(DFS)算法思路若已知左子树和右子树的深度 aaa 和 bbb,则该二叉树的深度为 max(a,b)+1max(a, b)+1max(a,b)+1,左右子树的深度以同样的方式计算,递归访问到空结点时退出。具体代码/** * Definition for a binary tree node. * public c原创 2021-03-22 16:27:39 · 317 阅读 · 0 评论 -
【JZ-54】二叉搜索树的第 k 大节点(二叉搜索树、递归)
题目原创 2021-03-22 14:03:29 · 245 阅读 · 0 评论 -
【JZ-53-II】0 ~ n-1中缺失的数字(二分查找)
目录题目方法一-暴力求解方法二-二分查找算法思路具体代码复杂度分析题目方法一-暴力求解即遍历数组,找到索引和数字不相等的元素即为缺失的数字。class Solution { public int missingNumber(int[] nums) { int i = 0; for(int num : nums){ if(num == i)i++; else break; } re原创 2021-03-21 21:28:20 · 169 阅读 · 0 评论 -
【JZ-53-I】在排序数组中查找数字(二分查找)
目录题目方法一-哈希表算法思路具体代码复杂度分析方法二-二分查找算法思路具体代码复杂度分析代码优化题目方法一-哈希表算法思路即不考虑数组有序的条件,直接遍历一遍数组统计每个数字的出现次数。具体代码class Solution { public int search(int[] nums, int target) { Map<Integer, Integer> dic = new HashMap<>(); for(int num :原创 2021-03-21 20:50:34 · 238 阅读 · 0 评论 -
【JZ-52】两个链表的第一个公共节点(链表、双指针)
目录题目解题思路具体代码复杂度分析题目解题思路双指针法创建两个指针pA和pB,分别初始化为链表A和B的头结点,然后向后逐节点遍历。当pA到达链表A尾部时,将其重定位到链表B的头结点;类似的,当pB到达链表B尾部时,将其重定位到链表A的头结点。若某一时刻pA和pB相遇,则该节点就是第一个公共结点。若两个链表存在相交,则末尾结点必然相同,因此当pA/pB到达链表结尾时,记录下链表A/B对应的元素,不相同则说明两个链表不相交。原理:A和B两个链表长度可能不同,但是A+B和B+A的长度是相同原创 2021-03-21 16:08:52 · 267 阅读 · 0 评论 -
【JZ-51】数组中的逆序对(归并排序)
题目解题思路n 最大为50000,所以暴力解法(双层循环)一定会超时。原创 2021-03-21 14:56:30 · 177 阅读 · 0 评论 -
【JZ-50】第一个只出现一次的字符(哈希表)
目录题目算法思路具体代码复杂度分析算法改进-有序哈希表题目算法思路遍历字符串,利用哈希表记录 【各字符出现次数是否大于1】,然后再一次遍历字符串找到第一个 【只出现了一次】 的字符。这里哈希表中的值可以设置为布尔值,因为只要出现的次数大于一就不满足条件了,设置为整型的话还需要不断加一,即 【键为字符,值为truetruetrue或falsefalsefalse】具体代码class Solution { public char firstUniqChar(String s) {原创 2021-03-20 22:09:28 · 157 阅读 · 0 评论 -
【JZ-49】丑数(数学、动态规划)
目录题目算法思路具体代码复杂度分析题目参考算法思路设丑数序列为 x1,x2,x3,...,xnx_1,x_2,x_3,...,x_nx1,x2,x3,...,xn,则下一个丑数 xn+1x_{n+1}xn+1 为以下三种情况中的最小值:xn+1={xa×2,a∈[1,n]xb×3,b∈[1,n]xc×5,c∈[1,n]x_{n+1}=\begin{cases}x_a\times2,&a\in[1,n]\\x_b\times3,&b\in[1,n]\\x_c\time原创 2021-03-20 20:56:18 · 181 阅读 · 0 评论 -
【JZ-48】最长不含重复字符的子字符串(动态规划、滑动窗口)
目录题目算法思路方法一-动态规划+哈希表具体代码:复杂度分析:方法二-动态规划+线性查找具体代码:复杂度分析:方法三-双指针+哈希表(滑动窗口)具体代码:复杂度分析:题目算法思路设 f(j)f(j)f(j) 代表以字符 s[j]s[j]s[j] 作为结尾的【最长不含重复字符的子字符串】的长度,字符 s[j]s[j]s[j] 左边距离最近的相同字符为 s[i]s[i]s[i],则转移方程为:当 i < 0时,说明字符 s[j]s[j]s[j] 左边没有相同字符,则 f(j)=f(j−1)+1原创 2021-03-20 16:52:10 · 484 阅读 · 0 评论 -
【JZ-47】礼物的最大价值(动态规划)
目录题目算法思路具体代码代码改进复杂度分析题目参考算法思路设 value(i,j)value(i,j)value(i,j) 表示单元格 (i,j)(i,j)(i,j) 的礼物价值, f(i,j)f(i,j)f(i,j) 表示从棋盘左上角走到单元格 (i,j)(i,j)(i,j) 的礼物最大价值,显然有转移方程:f(i,j)=max{f(i−1,j), f(i,j−1)}+value(i,j)f(i,j)=max\{f(i-1,j),\ f(i,j-1) \}+value(i,j)f(i,j原创 2021-03-20 15:00:01 · 321 阅读 · 0 评论 -
【JZ-46】把数字翻译成字符串(动态规划)
目录题目算法思路方法一-字符串遍历具体代码复杂度分析方法二-数字求余具体代码复杂度分析题目参考算法思路将数字 numnumnum 的位数记为 nnn,第 iii 位数字(从高位开始数)记为 xix_ixi,设 f(i)f(i)f(i) 代表以 xix_ixi 为结尾的数字的翻译方案数,则转移方程为:f(i)={f(i−1)+f(i−2),if 10∗xi−1+xi∈[10,25]f(i−1),if 10∗xi−1+xi∉[10,25]f(i)=\begin{cases}f原创 2021-03-19 22:39:37 · 233 阅读 · 0 评论 -
【JZ-45】把数组排成最小的数(排序、字符串)
目录题目算法思路具体代码a. 快排b. 内置排序函数复杂度分析题目参考算法思路设数组中任意两个数字的字符串为 xxx 和 yyy,则:若x+y>y+xx+y>y+xx+y>y+x,则xxx “大于” yyy,即xxx应该排在yyy的右边;若x+y<y+xx+y<y+xx+y<y+x,则xxx “小于” yyy,即xxx应该排在yyy的左边该规则的自反性和对称性很显然,传递性证明过程具体代码a. 快排参考class Solution { public String minN原创 2021-03-19 17:56:59 · 253 阅读 · 0 评论 -
【JZ-44】数字序列中某一位的数字(数学)
题目原创 2021-03-18 22:02:32 · 406 阅读 · 0 评论 -
【JZ-43】1~n整数中1出现的次数(数学)
目录题目算法思路情况一:cur=0情况二:cur=1情况三:cur=2,3,...,9变量递推:具体代码复杂度分析题目参考算法思路1 ~ n 的整数中 1 出现的总次数,也就是每一位上1出现的次数之和。设数字 n 为 a 位数,将 n 写作 nana−1...n2n1n_an_{a-1}...n_2n_1nana−1...n2n1,当前位 nin_ini 记为 curcurcur,高位部分nana−1...ni+2ni+1n_an_{a-1}...n_{i+2}n_{i+1}nana−原创 2021-03-17 22:26:05 · 236 阅读 · 0 评论 -
【JZ-42】连续子数组的最大和(动态规划)
题目参考算法思路用 aia_iai 代表 nums[i]nums[i]nums[i],用 f(i)f(i)f(i) 代表以 nums[i]nums[i]nums[i] 结尾的连续子数组的最大和,显然我们要求的就是所有 f(i)f(i)f(i) 中的最大值。动态规划转移方程:若f(i−1)≤0f(i-1) \leq0f(i−1)≤0:f(i)=aif(i)=a_if(i)=ai若f(i−1)>0f(i-1)>0f(i−1)>0:f(i)=f(i−1)+aif(i)=f(i-原创 2021-03-17 17:19:39 · 295 阅读 · 0 评论 -
【JZ-41】数据流中的中位数(堆)
目录题目算法思路算法流程addNum(int num):findMedian():具体代码复杂度分析题目参考算法思路重点是每次插入新的数据后都要使得列表中的数保持有序,然后返回中间元素。为了使得时间复杂度尽可能小,可以分别建立小根堆和大根堆,前者保存列表中较大的一半数据,后者保存列表中较小的一半数据,这样要获得中位数直接根据两个堆的堆顶数据进行计算即可。算法流程假设共有 N 个数据,小根堆 A 中存放 m 个,大根堆 B 中存放 n 个。当 N 为偶数时,m = n = N/2;当 N 为奇数时原创 2021-03-17 15:26:32 · 143 阅读 · 0 评论 -
【JZ-40】最小的k个数(快排、堆、排序)
题目原创 2021-03-16 22:16:01 · 502 阅读 · 0 评论 -
【JZ-39】数组中出现次数超过一半的数字(哈希表、排序、投票)
目录题目方法一-哈希表统计法算法思路具体代码复杂度分析方法二-排序算法思路具体代码复杂度分析方法三-投票算法思路具体代码复杂度分析题目参考方法一-哈希表统计法算法思路该方法最容易想到,即用一个哈希表来统计数组中各个数字出现的次数,超过数组长度一半的就是“众数”。对于哈希映射中的每个键值对,key表示一个元素,value表示该元素出现的次数。具体代码class Solution { public int majorityElement(int[] nums) { Map原创 2021-03-15 21:49:49 · 173 阅读 · 0 评论 -
【JZ-38】字符串的排列(DFS、回溯)
目录题目算法思路具体代码复杂度分析题目参考算法思路当字符串中没有重复的字符时,共有 n!n!n! 种不同排列,即,先固定第一位字符(有 n 种选择),再固定第二位字符(有 n-1 种选择),…,最后固定第 n 位字符(1种选择),很容易想到递归的方法。但题设中并未限制输入的字符串中没有重复的字符,所以需要剪枝,保证在固定某一位的字符时,遇到重复的字符直接跳过。递归函数dfs():递归参数:当前固定位 xxx终止条件:x = c.length - 1时,代表所有位都已固定,则将当前排列转化为字原创 2021-03-14 23:48:02 · 179 阅读 · 0 评论 -
【JZ-37】序列化二叉树(树、设计)
目录题目算法思路算法流程序列化serialize(root):反序列化Deserialize(data):具体代码复杂度分析序列化函数:反序列化函数:题目参考算法思路序列化的结果实际上是二叉树==层序遍历(BFS)==的结果,为了完整表示二叉树,叶节点下的 nullnullnull 也要记录下来。示例中的二叉树各节点和索引的对应关系为:node.valnode.valnode.valnodenodenode的索引node.leftnode.leftnode.left的索引node.原创 2021-03-14 22:23:18 · 250 阅读 · 0 评论 -
【JZ-36】二叉搜索树与双向链(二叉搜索树、递归)
题目原创 2021-03-14 11:29:27 · 176 阅读 · 0 评论