【2021-5】LeetCode每日一题复盘

五月也有徽章了,表示完成了31天挑战。
【2021-5】LeetCode每日一题复盘_第1张图片

Week 1: May 1st - May 7th

【2021-5】LeetCode每日一题复盘_第2张图片

Prefix and Suffix Search

题目大意:
从字典中查找单词,前缀和后缀都满足查询条件。返回单词的索引,如果有多个匹配的单词,返回索引最大的;如果没有匹配的单词,返回-1.

思路:
构造一个map,key为 prefix+"#"+suffix, value为单词索引。
遍历每个单词,每个单词的key组合有len^2种,分别将它们put到HashMap中。
查询匹配单词最大索引,就是HashMap的get操作。

提示知识点:
HashMap 穷举

代码链接:
745.prefix-and-suffix-search.java

Course Schedule III

题目大意:
一共有n门课程,有持续时间和最晚完成时间,问最多能学完几门课程。

思路:
首先对课程按照最晚完成时间升序排序。
遍历课程,添加当前课程
如果添加后,没有超出最晚完成时间,则递增当前总时间。
如果超出最晚完成时间,则删除之前课程中花费最多的课程,当前总时间减去此前花费最多的时间。
最后返回优先队列的元素个数。

提示知识点:
PriorityQueue 贪心

代码链接:
630.course-schedule-iii.java

Running Sum of 1d Array

题目大意:
返回数组的当前和数组

思路:
遍历数组累加即可,原地操作,当前元素值加上前一个元素值。

提示知识点:

代码链接:
1480.running-sum-of-1-d-array.java

Non-decreasing Array

题目大意:
一个数组可能不是/是非递减数组,能否修改最多一个元素的值使它成为非递减数组。

思路:
当出现nums[i] < nums[i-1]时,
使用修改机会,可以有两种修改方式,
如果i>=2 且nums[i] 否则,将nums[i-1]修改为nums[i]。
只有一次修改机会,再次出现nums[i] < nums[i-1]时,则返回false。

提示知识点:

代码链接:
665.non-decreasing-array.java

Jump Game II

题目大意:
数组的每个值表示当前位置能跳的最远长度,求最少的步数从起点跳到终点。

思路:
贪心法
要用最少的步数,那么每一次都要保证下一跳能跳到可能的最远位置。
step表示当前位置。curMaxStep表示当前能跳的最大步数,从【1, curMaxStep】依次判断,max表示下一跳能跳到的最远位置,下一跳能跳到的最远位置为nums[i+step]+i。求出这个最远位置。步数加1,跳到这个位置。直到跳到终点。

动态规划法
定义步数动态规划数组,step[i]表示到达i位置所需的最小步数,step[len-1]即为所求。
双重循环,外层为遍历nums数组,内层为[1,nums[i]],然后更新动态规划数组step,方程式为
steps[i+j] = steps[i+j] == 0 ? steps[i]+1 : Math.min(steps[i+j], steps[i]+1);

提示知识点:
贪心 动态规划

代码链接:
45.jump-game-ii.java

Convert Sorted List to Binary Search Tree

题目大意:
将有序链表转化为平衡的二叉排序树

思路:
不要想得太复杂,题目不是要你去实现红黑树的插入。是转化链表,而且链表已经有序。
思路很简单,用递归法,找到链表的中间节点并将链表一分为二,中间节点作为根节点,左边的链表作为左子树,右边的部分(包含中间节点)作为右子树。

提示知识点:
树 递归 链表二分法

代码链接:
109.convert-sorted-list-to-binary-search-tree.java

Delete Operation for Two Strings

题目大意:
使两字符串相等的最短编辑距离。编辑只能是每次删除其中一个字符串的一个字符。

思路:
对最短编辑距离做了下改变。
最短编辑距离可以替换,这个只能删除,因此,
当word1.charAt(i-1) != word2.charAt(j-1)时,dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1])+1,删除word1位置i-1的字符或者删除word2位置j-1的字符。

提示知识点:
动态规划

代码链接:
583.delete-operation-for-two-strings.java

Week 2: May 8th - May 14th

【2021-5】LeetCode每日一题复盘_第3张图片

Super Palindromes

题目大意:
求区间内的超级回文数。超级回文数定义为:这个数是回文数并且是回文数的平方。区间边界值最大为18位数。

思路:
最大为18位数,我们需要遍历最大9位数的回文数,然后平方,判断这个平方值是否是回文数。
拼接 最大9位数的回文数,最多再遍历5位数,这个回文数可能是奇数位,也可能是偶数位。
如果是奇数位,我们拼接的时候,遍历只需要从1到100000(不包含100000,
因为最大是99999,拼接最大值为999999999(9位数),平方正好18位数。而如果是100000,拼接最大值是11位数,平方是22位数,一定超过右边界)。
以此类推,如果是偶数位,我们拼接的时候,遍历只需要从1到10000(不包含10000。如果包含,拼接最大值为10位数,平方为20位数,一定超过右边界)。
拼接好一个回文数,计算平方,判断平方数是否是回文数,是的话超级回文数加一。

提示知识点:
数学
java中int是4字节,32位,2^32-1,最多是2开头的10位数
long是8字节,64位,2^64-1,最多是9开头的19位数
因此本题的边界值应转化为long型

代码链接:
906.super-palindromes.java

Construct Target Array With Multiple Sums

题目大意:
给出一个目标数组,开始的时候你有一个均为1的等长数组,每次操作你都可以将一个元素置为当前数组中所有元素和,问是否能通过一系列这样的操作,得到目标数组。

思路:
目标数组的最大值,应该是上一步数组中所有元素的和。因此,模拟这个过程的逆过程:用最大值减去其余元素的和,然后把这个值加入到优先队列中,直到所有元素都为1。
为了避免超时,把减法优化为求余,减少重复的次数。求余的时候:如果max < sum或者sum = 0或者max % sum为0,这都是不可能的情况;如果sum为1,这种情况只有数组长度为2时发生,也是可能得到目标数组的。其他情况直到优先队列最大元素为1,表示可能。

提示知识点:
数组 优先队列

代码链接:
1354.construct-target-array-with-multiple-sums.java

Count Primes

题目大意:
计算小于n的数中素数的个数。0和1不是素数。

思路:
1、常见的思路是从2到n,依次判断这个数是不是素数。
判断x是不是素数比较常见的方法,是依次判断从2到sqrt(x)(包含),x能否整除,能被整除,则不是。
2、排除法。
排除所有非素数,定义一个长度为n的dp数组标记0~n-1是否是素数,一开始假设2到n-1都是素数。从2开始遍历数组,如果当前数x是素数,那么
x^2, x^2+kx就不是素数。排除所有非素数后,遍历标记数组,得到素数个数。时间复杂度O(n log log n)。

提示知识点:
数学

代码链接:
204.count-primes.java

Maximum Points You Can Obtain from Cards

题目大意:
给一个数组,每个元素代表卡片上的分数,你每次可以从数组的开始或结尾处取一张卡片,一共取k张卡片,得到一个总分数。问最多能获得多少分。

思路:
模拟这个过程的逆过程,在数组中取连续n-k张卡片,得到最少的分数。那么首/尾取k张卡片,得到最大分数即为所有卡片分数和减去之前求得的最小分数。
滑动窗口,求数组中n-k个连续数的最小值。

提示知识点:
滑动窗口

代码链接:
1423.maximum-points-you-can-obtain-from-cards.java

Range Sum Query 2D - Immutable

题目大意:
给出一个二维数组,然后给出区域左上坐标和右下坐标,求出区域所有数字和。

思路:
定义一个二维动态规划数组sum[m+1][n+1],m是原二维数组的行数,n是原二维数组的列数。sum[i+1][j+1]表示原二维数组左上角(0,0)与右下角(i,j)围成的区域的和。加1是考虑到i,j可能为0,方程中i-1,j-1会数组越界,对于这种特殊情况,也一般对待,就扩容加1了。
sum[i+1][j+1] = matrix[i][j] + sum[i+1][j] + sum[i][j+1] - sum[i][j];

左上角(row1, col1)与 右下角(row2, col2)围成的区域元素和为:
sum[row2+1][col2+1] - sum[row2+1][col1] - sum[row1][col2+1] + sum[row1][col1];

提示知识点:
动态规划

代码链接:
304.range-sum-query-2-d-immutable.java

Ambiguous Coordinates

题目大意:
给出模糊坐标字符串,求所有可能的还原坐标字符串。
模糊字符串,是原始坐标去掉小数点、逗号分隔符和空格后生成的字符串。
原始坐标字符串不存在0.0, 00.1, 00, 001, 0.10这样的非法数,小数点前也必须有数字,像.1是非法的。

思路:
将字符串分为两部分,分别给两部分还原,然后拼接。
还原一个字符串的过程:
1.如果字符串长度为1,不能添加小数点,添加到结果列表,直接返回。否则进入步骤2
2.如果字符串0开头,分为两种情况:
如果结尾也是0,无效,返回空列表
如果结尾不是0,只有一种情况,小数点在第一个0后面,添加到结果列表,直接返回。
否则进入步骤3。
3.如果字符串结尾是0,不能添加小数点,添加到结果列表,直接返回。
否则进入步骤4。
4.遍历出len-1(字符串长度)种情况,添加到结果列表。

提示知识点:
穷举

代码链接:
816.ambiguous-coordinates.java

Flatten Binary Tree to Linked List

题目大意:
将二叉树转化为链表,链表还是原来的树节点,只不过左子树永远是空,链表的下一个节点是树节点的右子树,链表的顺序与二叉树前序遍历顺序一样。

思路:
1.不借助栈的解法:
从根节点开始,遍历左子树p,如果左子树的右子树不为空,一直遍历到最右子树,p指向最右子树;如果左子树的右子树为空,那么p不变,继续。
接下来,
p.right = root.right;
root.right = root.left;
root.left = null;
完成一轮转化。
接下来,root的左子树为空了,root指向它的右子树,继续下一轮,直到root为空,转化完成。

2.借助栈的解法。
将树的右子树入栈。当左子树节点都遍历完了,再出栈遍历右子树。

提示知识点:

代码链接:
114.flatten-binary-tree-to-linked-list.java

你可能感兴趣的:(面试编程题,Java编程小练习,leetcode,算法)