力扣.1054距离相等的条形码力扣767.重构字符串力扣47.全排列II力扣980.不同路径III力扣509.斐波那契数列(记忆化搜索)

目录

力扣.1054距离相等的条形码

力扣767.重构字符串

力扣47.全排列II

力扣980.不同路径III

力扣509.斐波那契数列(记忆化搜索))


力扣.1054距离相等的条形码

是否策略正确

但是假如 1 2 2 此时 1_2 此时中间只能填写2,但是就不对了,所以,限定条件,先处理出现次数最多的次数,其余无所谓

2_2

证明:题目一定有解,性质:两个两个一组

(n+1)/2组,出现次数最多的次数,一定是小于(n+1)/2个,那么

假如出现次数最多的,等于(n+1)/2,一定正确

第二个,最多的,小于(n+1)/2, 假如你 前面 o _ o_ o_ o_ x_ x_x 假如你第二个没填写完,就还是x,但是你不可能说是x填重复的,换句话,x绝对不可能绕过一圈来再次相邻,

复制代码
class Solution {
       public int[] rearrangeBarcodes(int[] barcodes) {
        Arrays.sort(barcodes);
        int n=barcodes.length;
        Map<Integer,Integer>map=new HashMap<>();
        int[]a=new int[n];
        int max=0;
        int maxcount=0;
//第一个点,该定义变量就去定义,不要老想着优化
        for(int i=0;i<n;i++){
            map.put(barcodes[i],map.getOrDefault(barcodes[i],0)+1);
            if(maxcount<map.get(barcodes[i])){
            max=barcodes[i];
            maxcount=map.get(barcodes[i]);
          }
        }

    //先处理出现次数最多的那个数字

        int index=0;
        //统计处那个字符数字最多,然后给他填上
//最难的一步就是maxcount你是否能理清楚
        for(int i=0;i<maxcount;i++){
         a[index]=max;
         index+=2;
        }
        //处理剩下的数,可以直接删除,也可以遍历时候跳过,不要太纠结
        map.remove(max);
        for(int x:map.keySet()){
            for(int i=0;i<map.get(x);i++){
                if(index>=n) index=1;
                a[index]=x;
                index+=2;
            }
        }
        return a;
    }
}

力扣767.重构字符串

跟上面那个题思路一样,只需要进行一个判断,是否满足条件就行。

max>(n+1)/2的情况下,就返回空字符串

复制代码
class Solution {
    public String reorganizeString(String s) {
        HashMap<Character,Integer>map=new HashMap<>();//(n+1)/2
        char[]a=s.toCharArray();
        int n=a.length;
        char max=a[0];
        int maxCount=0;
        for(int i=0;i<n;i++){
            map.put(a[i],map.getOrDefault(a[i],0)+1);
            if(maxCount<map.get(a[i])){
                max=a[i];
                maxCount=map.get(a[i]);
            }
        }
        if(maxCount>(n+1)/2)return "";
        else{
            StringBuffer sb=new StringBuffer();
            int index=0;
            for(int i=0;i<maxCount;i++){
                a[index]=max;
                index+=2;
            }
            map.remove(max);
            for(char x:map.keySet()){
                for(int i=0;i<map.get(x);i++){
                if(index>=n)index=1;
                a[index]=x;
                index+=2;
            }
         }
            return sb.append(a).toString();
        }

    }
}

力扣47.全排列II

1.同一个节点都所有分支中,相同的元素只可以选择一次

同一个数只能使用一次

并且我们需要对数组,进行一个排序,去确定 check[i]==true||nums[i]与nums[i-1]是否相同

同一层的话,不用考虑 check[i-1]==false

考虑不合法的分支(这里的i不可以等于0,0一定合法,不用判断)

check[i]==true ||(i!=0&&nums[i]==nums[i-1]&&check[i-1]==false)

假如i位置是true代表当前位置已经被使用了,或者,当前位置的前一个没有被使用,但是我和你是在一层,换句话说,我们属于一层,那么就应该剪枝

考虑合法的分支(这里面的i是可以等于0的(

check[i]=false&&(nums[i]!=nums[i-1]||check[i-1]==true(此时的条件是a[i]=a[i-1]) )

复制代码
class Solution {
    List<List<Integer>>ret=new ArrayList<>();
    List<Integer>ans=new ArrayList<>();
    boolean[]check;
    int n;
    //伴随着就是如何剪枝
    public void dfs(int pos,int []nums){
    if(pos==n){ ret.add(new ArrayList<>(ans)); return ;}
    for(int i=0;i<n;i++){
    if((check[i]==true)||(i!=0&&check[i-1]==false&&nums[i]==nums[i-1])){continue;}    
    check[i]=true;
    ans.add(nums[i]);   
    dfs(pos+1,nums);
    ans.remove(ans.size()-1);
    check[i]=false;;
      }
    }

    public List<List<Integer>> permuteUnique(int[] nums) {
     n=nums.length;
     Arrays.sort(nums);
     check=new boolean[n];
     dfs(0,nums);    
     return ret;
    }
}

力扣980.不同路径III

step++,然后到达终点之后,路径++,然后不断递增就好

这个要注意,最后才调用这个函数要让step走完

复制代码
class Solution {
    int pathCount=0;
    int[]dx={0,0,1,-1};
    int[]dy={1,-1,0,0};
    int n;
    int m;
    int step;
    boolean[][]vis;
    public void dfs(int count,int[][]grid,int i,int j){
        if(grid[i][j]==2){
            if(count==step)pathCount++;
            return;
            }
        for(int k=0;k<4;k++){
         int x=i+dx[k];
         int y=j+dy[k];
         if(
            x>=0&&x<n&&y>=0&&y<m
         &&vis[x][y]==false
         &&(grid[x][y]==0||grid[x][y]==2)
         ){
            vis[x][y]=true;
            dfs(count+1,grid,x,y);
            vis[x][y]=false;
         }
      }  
    }
    public int uniquePathsIII(int[][] grid) {
        n=grid.length;
        m=grid[0].length;
        vis=new boolean[n][m];
        int bx=0;
        int by=0;
        //这么判断是否走完全了
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(grid[i][j]==1){
                      bx=i;
                      by=j;
                      vis[bx][by]=true;
                }
                else if(grid[i][j]==0||grid[i][j]==2)step++;
            }
        }

        dfs(0,grid,bx,by);
        return pathCount;
    }
}

力扣509.斐波那契数列(记忆化搜索)

存储在map,假如有值,直接返回,就不用再去递归了。

复制代码
class Solution {
    Map<Integer,Integer>map=new HashMap<>();
    public int dfs(int n){
     if(map.containsKey(n)){
        return map.get(n);
     }   
    map.put(n,dfs(n-1)+dfs(n-2));
    return map.get(n);
    }
    public int fib(int n) {
        map.put(0,0);
        map.put(1,1);
        return dfs(n);
    }
}
相关推荐
小信丶1 小时前
Spring 6 的 @HttpExchange 注解:声明式 HTTP 客户端的现代化利器
java·spring·http
Nie_Xun2 小时前
ROS1 go2 vlp16 局部避障--3 篇
算法
野犬寒鸦3 小时前
多级缓存架构:性能与数据一致性的平衡处理(原理及优势详解+项目实战)
java·服务器·redis·后端·缓存
帧栈5 小时前
开发避坑指南(58):Java Stream 按List元素属性分组实战指南
java
Da Da 泓5 小时前
LinkedList模拟实现
java·开发语言·数据结构·学习·算法
海琴烟Sunshine5 小时前
Leetcode 14. 最长公共前缀
java·服务器·leetcode
未知陨落5 小时前
LeetCode:68.寻找两个正序数组的中位数
算法·leetcode
城管不管6 小时前
Lambda
java
龙茶清欢6 小时前
5、urbane-commerce 微服务统一依赖版本管理规范
java·运维·微服务
努力学习的小廉7 小时前
我爱学算法之—— 模拟(下)
c++·算法