leetcode算法题解(Java版)-11-贪心大法

简介: 多了一个条件,就是有重复数字出现。那可以考虑先排序,然后递归选择在相应位置放置数字的时候,可以添加判断是否被用过,也就是和前面那个比较一下:如果前面那个数和它一样值,而且目前的used 显示false那说明这个数已经在这个位置被用过了,而且已经计入了结果res中。

一、全排列变式(递归)

题目描述

Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]have the following unique permutations:
[1,1,2],[1,2,1], and[2,1,1].

思路

  • 多了一个条件,就是有重复数字出现。那可以考虑先排序,然后递归选择在相应位置放置数字的时候,可以添加判断是否被用过,也就是和前面那个比较一下:如果前面那个数和它一样值,而且目前的used 显示false那说明这个数已经在这个位置被用过了,而且已经计入了结果res中。

代码

import java.util.ArrayList;
import java.util.Arrays;

public class Solution {
    public ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
        ArrayList<ArrayList<Integer>> res=new ArrayList<>();
        int len=num.length;
        if(num==null||len==0){
            return res;
        }
        boolean [] used=new boolean[len];
        ArrayList<Integer> list=new ArrayList<>();
        Arrays.sort(num);
        dfs(list,num,used,res);
        return res;
    }
    
    public void dfs(ArrayList<Integer> list,int [] num,boolean [] used,ArrayList<ArrayList<Integer>> res){
        if(list.size()==num.length){
            res.add(new ArrayList<Integer>(list));
            return ;
        }
        for(int i=0;i<num.length;i++){
            if(i>0&&num[i]==num[i-1]&&!used[i-1]){//如果它前一个和它一样的数现在没有被用过,那就跳过,
                //说明之前那个数已经形成过结果list之一了,目前这个分支处于回溯阶段。。。有点绕,希望能明白
                continue;
            }
            if(!used[i]){
                used[i]=true;
                list.add(num[i]);
                dfs(list,num,used,res);
                list.remove(list.size()-1);
                used[i]=false;
            }
        }
    }
}

二、贪心

题目描述

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A =[2,3,1,1,4], returntrue.
A =[3,2,1,0,4], returnfalse

思路

  • 贪心的题,每走一步,跟新一下从当前这个位置所能到达的最大距离。这就是这题的贪心,贪心一般证明很难,但是可以逻辑简单想一下,肯定是能走的距离越大越好,越有可能到达终点,再说,如果最大距离都不能到终点,那其他情况更加不可能了。

代码

public class Solution {
    public boolean canJump(int[] A) {
        int maxlen=A[0];
        for(int i=1;i<A.length;i++){
            if(maxlen==0){
                return false;
            }
            maxlen-=1;
            maxlen=Math.max(maxlen,A[i]);
            //if(maxlen+i==A.length-1){//剪枝
            //    return true;
           // }
        }
        return true;
    }
}

三、动态规划or贪心

题目描述

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A =[2,3,1,1,4]
The minimum number of jumps to reach the last index is2. (Jump1step from index 0 to 1, then3steps to the last index

思路

  • dp解法:
  • 题目想考察的是贪心,想了一下,思绪有点乱。先看一下动态规划的解法。
  • 首先,满足dp的条件:1.子问题的最优解也是全局的最优解,有最优子结构;2.当前状态只依赖于它上一个状态,与怎么到达它上一个状态的路径无关。

代码

public class Solution {
    public int jump(int[] A) {
        int [] dp=new int[A.length];//存放起点到各点的最小步数
        for(int i=0;i<A.length;i++){
            int maxpos=Math.min(i+A[i],A.length-1);
            for(int j=i+1;j<=maxpos;j++){
                if(dp[j]==0){
                    dp[j]=dp[i]+1;
                }
            }
            if(dp[A.length-1]!=0){
                break;
            }
        }
        return dp[A.length-1];
    }
}

思路二

  • 贪心解法:
  • 贪心大法好,但真的难想明白。。首先,要设置三个值:当前位置(是一个区域:从i~furthest_pre中,区域中的点中能到达的最大位置)所能到达的最大位置(furthest_cur),当前位置的上一个位置(也是区域)所能到达的最大位置(furthest_pre),还有就是所走的步数。
  • 有一点可能有点会懵,furthest_cur是还没有step++的时候,具体结合代码,也就是是一个预判能走到的但还没走的状态。
  • 感觉讲的还是有点乱,现在抛开代码,想象我们站在题目给的数组的开头位置:从开始位置到开始位置能走到的最大距离(furthest_pre)之间构成了一块区域,然后我们开始一格一格走,每走一下刷新一下当前这块区域能到的最大位置(furthest_cur),如果走到从开始位置走到了furthest_pre那我们也刷新出了最大的furthest_cur,如果furthest_cur比终点大,那恭喜!再跳一不就到终点了!可以开始跳一步咯!然后重复上述的动作,直到到达终点。
  • 如果能一步到最大位置furthest_pre,那肯定能到一步到它前面那块区域的某一位置,实行下一步跳,跳到furthest_cur
  • 给一个测试用例,可以在纸上画画:
4 1 6 9 7 4 5 0 6 8 1 2 3 5 8 0 2 1 2

代码

public class Solution {
    public int jump(int[] A) {
        int len=A.length;
        if(len==0||A==null){
            return 0;
        }
        int furthest_cur=0;
        int furthest_pre=0;
        int steps=0;
        for(int i=0;i<len;i++){
            if(furthest_pre>=len){
                return steps;
            }
            if(i>furthest_pre){
                furthest_pre=furthest_cur;
                steps++;
            }
            furthest_cur=Math.max(furthest_cur,A[i]+i);
        }
        return steps;
    }
}
目录
相关文章
|
30天前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
254 35
|
1月前
|
存储 算法 搜索推荐
《数据之美》:Java数据结构与算法精要
本系列深入探讨数据结构与算法的核心原理及Java实现,涵盖线性与非线性结构、常用算法分类、复杂度分析及集合框架应用,助你提升程序效率,掌握编程底层逻辑。
|
1月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
5月前
|
存储 算法 安全
Java中的对称加密算法的原理与实现
本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。
413 58
|
4月前
|
机器学习/深度学习 算法 Java
Java实现林火蔓延路径算法
记录正在进行的森林防火项目中林火蔓延功能,本篇文章可以较好的实现森林防火蔓延,但还存在很多不足,如:很多参数只能使用默认值,所以蔓延范围仅供参考。(如果底层设备获取的数据充足,那当我没说)。注:因林火蔓延涉及因素太多,如静可燃物载量、矿质阻尼系数等存在估值,所以得出的结果仅供参考。
70 4
|
3月前
|
运维 监控 算法
基于 Java 滑动窗口算法的局域网内部监控软件流量异常检测技术研究
本文探讨了滑动窗口算法在局域网流量监控中的应用,分析其在实时性、资源控制和多维分析等方面的优势,并提出优化策略,结合Java编程实现高效流量异常检测。
140 0
|
4月前
|
存储 负载均衡 算法
我们来说一说 Java 的一致性 Hash 算法
我是小假 期待与你的下一次相遇 ~
163 1
|
4月前
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
172 0
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
247 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
354 2

热门文章

最新文章