本题典型的动态规划问题,我们创建一个二维数组dp来记录对grid数组遍历到的每一位的礼物的最大价值,值得一提的是我们创建的dp数组的行列都比grid数组多1,这是为了解决边界问题。
class Solution {
public int maxValue(int[][] grid) {
int row = grid.length;
int col = grid[0].length;
int[][] dp = new int[row+1][col+1];
for(int i = 1;i<=row;++i){
for(int j = 1;j<=col;++j){
dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1])+grid[i-1][j-1];
}
}
return dp[row][col];
}
}
本题也是典型的动态规划问题,我们创建两个变量:cost用来记录当前遍历到的价格中最小价格;profit用来记录当前的最大利润,那么遍历一遍数组即可得到最大利润。
class Solution {
public int maxProfit(int[] prices) {
int cost = Integer.MAX_VALUE;
int profit = 0;
for(int price:prices){
cost = Math.min(cost,price);
profit = Math.max(profit,price-cost);
}
return profit;
}
}
在排序数组中查找数字首选二分查找。问题是我们要得到该数字在数组中出现的次数,解决方法是:在初次找到该数字时,我们将左右指针移到该数字下标,再分别往两边走,直到下标所指数字不等于该数字时,指针相减再减一即可。
class Solution {
public int search(int[] nums, int target) {
int l = 0;
int r = nums.length-1;
int mid = (l+r)/2;
int res = 0;
while(l <= r){
if(nums[mid] > target){
r=mid-1;
mid=(l+r)/2;
}
else if(nums[mid] < target){
l = mid+1;
mid=(l+r)/2;
}else{
l=mid;
r=mid;
while(l>=0 && nums[l] == target) l--;
while(r<nums.length && nums[r] == target) r++;
res = r-l-1;
return res;
}
}
return res;
}
}
本题数组长度为n,而且数组中所有数字的大小都在0~n之内,但是0 ~ n是n+1个数,由于数组长度为n,那么必定有一个数不存在,我们就是要找到这个数。
排序数组中的查找,首选二分查找。根据题目描述,该数组下标与其对应的数应该是相等的关系,当我们遇到下标与其对应的数不等的情况时,该数组下标就是我们要找的数。
class Solution {
public int missingNumber(int[] nums) {
int l = 0, r = nums.length-1;
while(l <= r){
int mid = (l+r)/2;
if(nums[mid] == mid) l=mid+1;
else r = mid-1;
}
return l;
}
}
本题在于判断五张牌是否是一个顺子,那么我们将所有不是顺子的情况一一列举出来就可以了:
1.五张牌中存在除0以外任意相同的牌
2.五张牌中最大的牌与最小的牌相差大于等于5
所以本题用Set集合来储存非0的牌再加以判断即可。
class Solution {
public boolean isStraight(int[] nums) {
Set<Integer> set = new HashSet<>();
int max = -1,min = 14;
for(int n:nums){
if(n == 0) continue;
max = Math.max(max,n);
min = Math.min(min,n);
if(max - min >=5) return false;
if(set.contains(n)) return false;
set.add(n);
}
return true;
}
}
本题的难点在于不能用除法,那么我们可以通过矩阵的上三角和下三角来计算乘积,正对角线中的元素全为1,代表本位乘1,下三角直接计算即可,上三角需要用tmp来储存临时结果,再代入计算。
class Solution {
public int[] constructArr(int[] a) {
int len = a.length;
if(len == 0) return new int[0];
int[] b = new int[len];
int tmp = 1;
b[0] = 1;
for(int i = 1;i<len;++i){
b[i] = b[i-1]*a[i-1];
}
for(int i = len-2;i>=0;--i){
tmp *= a[i+1];
b[i] *=tmp;
}
return b;
}
}
代码参考LeetCode作者:Krahets