力扣.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);
    }
}
相关推荐
渣哥6 小时前
你遇到过 ConcurrentModificationException 吗?其实很常见
java
lunzi_fly6 小时前
【源码解读之 Mybatis】【基础篇】-- 第1篇:MyBatis 整体架构设计
java·mybatis
久菜盒子工作室7 小时前
量化金融|基于算法和模型的预测研究综述
算法·金融
JIngJaneIL7 小时前
汽车租赁|基于Java+vue的汽车租赁系统(源码+数据库+文档)
java·vue.js·spring boot·汽车·论文·毕设·汽车租赁系统
渣哥7 小时前
有一天,我和 CopyOnWriteArrayList 杯“线程安全”的咖啡
java
叽哥7 小时前
Kotlin学习第 3 课:Kotlin 流程控制:掌握逻辑分支与循环的艺术
android·java·kotlin
杨杨杨大侠7 小时前
第5章:实现Spring Boot集成
java·github·eventbus
华仔啊7 小时前
工作5年没碰过分布式锁,是我太菜还是公司太稳?网友:太真实了!
java·后端
尚久龙7 小时前
安卓学习 之 图片控件和图片按钮
android·java·学习·手机·android studio·安卓