2016. 增量元素之间的最大差值 / 39. 组合总和

2016. 增量元素之间的最大差值【简单题】【每日一题】

思路:【前缀最小值】

  1. 我一开始是直接暴力两层for循环的,然后这用时让我觉得事情不对,看了题解的方法,嗯,我还是那个原来的菜鸡。
  2. 因为数组长度大于2,所以定义前半部分的最小值(即前缀最小值)premin = nums[0]。
  3. 定义ans初值为-1,即当找不到符合题意的数时直接返回ans=-1。
  4. 从下标1开始遍历整个数组,如果当前元素小于等于premin,说明自这个元素往前,当前元素是最小的,于是将前缀最小值premin更新为当前元素;如果当前元素大于premin,说明找到了一个满足题意的数,且如果不跟后边元素对比的话,当前元素与premin的差就是最大差值,那么将ans更新为当前元素与premin的差,同时还需要跟数组后边的元素可能构成的最大差值比较谁更大,因此此时实际上应将ans更新为ans和当前元素与premin差值 这两者的最大值。
  5. 最后返回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. 组合总和【中等题】

思路:【回溯+剪枝】

  1. 题解大概有两种回溯思路,一种是选中当前数,然后继续从当前数开始选,每选中一次就将target-=当前数,直到target等于0时,将选中的数存放的列表存入ans列表中,当target<0时,说明选数失败,需要逐步向上退,直到选中数之后不会失败为止。另一种思路是,回溯当前数,观察当前数的下一个数,如果无法观察下一个数,那么判断当前数是否小于等于target,如果是,那么选中当前数,并将其添加到list列表中,然后继续回溯当前数,并将target-=当前数,直到回溯返回为止,回溯返回就将当前数在列表list中移除,返回上一级回溯。

  2. 两种思路都学了一遍。之前也没怎么学过回溯,今天花半天时间算是恶补了一点。

代码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);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值