2016. 增量元素之间的最大差值【简单题】【每日一题】
思路:【前缀最小值】
- 我一开始是直接暴力两层for循环的,然后这用时让我觉得事情不对,看了题解的方法,嗯,我还是那个原来的菜鸡。
- 因为数组长度大于2,所以定义前半部分的最小值(即前缀最小值)premin = nums[0]。
- 定义ans初值为-1,即当找不到符合题意的数时直接返回ans=-1。
- 从下标1开始遍历整个数组,如果当前元素小于等于premin,说明自这个元素往前,当前元素是最小的,于是将前缀最小值premin更新为当前元素;如果当前元素大于premin,说明找到了一个满足题意的数,且如果不跟后边元素对比的话,当前元素与premin的差就是最大差值,那么将ans更新为当前元素与premin的差,同时还需要跟数组后边的元素可能构成的最大差值比较谁更大,因此此时实际上应将ans更新为ans和当前元素与premin差值 这两者的最大值。
- 最后返回ans。
代码:
class Solution {
public int maximumDifference(int[] nums) {
int ans = -1;
int len = nums.length,premin = nums[0];
for (int i = 1; i < len; i++) {
if (nums[i]<=premin){
premin = nums[i];
}else {
ans = Math.max(ans,nums[i]-premin);
}
}
return ans;
}
}
39. 组合总和【中等题】
思路:【回溯+剪枝】
题解大概有两种回溯思路,一种是选中当前数,然后继续从当前数开始选,每选中一次就将target-=当前数,直到target等于0时,将选中的数存放的列表存入ans列表中,当target<0时,说明选数失败,需要逐步向上退,直到选中数之后不会失败为止。另一种思路是,回溯当前数,观察当前数的下一个数,如果无法观察下一个数,那么判断当前数是否小于等于target,如果是,那么选中当前数,并将其添加到list列表中,然后继续回溯当前数,并将target-=当前数,直到回溯返回为止,回溯返回就将当前数在列表list中移除,返回上一级回溯。
两种思路都学了一遍。之前也没怎么学过回溯,今天花半天时间算是恶补了一点。
代码1:
class Solution {
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(candidates);
List<Integer> list = new ArrayList<>();
dfs(target,list,0,candidates,ans);
return ans;
}
public static void dfs(int target, List<Integer> list, int index, int[] candidates,List<List<Integer>> ans){
if (target == 0){
ans.add(new ArrayList<>(list));
return;
}
if (target < 0){
return;
}
for (int i = index; i < candidates.length; i++) {
if (target>=candidates[i]){
list.add(candidates[i]);
dfs(target-candidates[i],list,i,candidates,ans);
list.remove(list.size()-1);
}
}
}
}
代码2:
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(candidates);
int end = 0;
for (int i = candidates.length-1; i >= 0 ; i--) {
if (candidates[i]<target){
end = i;
break;
}else if (candidates[i] == target){
ans.add(new ArrayList<>());
ans.get(0).add(target);
end = i-1;
break;
}
}
List<Integer> list = new ArrayList<>();
dfs(target,list,0,end,candidates,ans);
return ans;
}
public void dfs(int target, List<Integer> list, int index, int end, int[] candidates,List<List<Integer>> ans){
if (target == 0){
ans.add(new ArrayList<>(list));
return;
}
if (index > end){
return;
}
//jump
dfs(target,list,index+1,end,candidates,ans);
//keep
if (target >= candidates[index]){
list.add(candidates[index]);
dfs(target-candidates[index],list,index,end,candidates,ans);
list.remove(list.size()-1);
}
}
}