LeetCode Hot100(回溯)

46. 全排列

题意

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

题解

因为是所有的排列组合,我们每一个位置都取一遍数组的所有元素看看有没有重复的即可

代码


import java.util.*;


public class Solution {
    public static void main(String[] args) {
        int []nums={1,2,3};
        permute(nums);

    }
    static List>  ans;
    public static List> permute(int[] nums) {
        ans=new ArrayList<>();
        int []arr=new int[nums.length];
        dfs(0,arr,nums);
        return ans;
    }
    public static void dfs(int x,int []arr,int []nums){
        if(x>=nums.length){
            HashMapmark=new HashMap<>();
            ArrayList brr=new ArrayList<>();
            for(int i=0;i

78. 子集

题意

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

题解

我们这边引入数学的一个概念,一个大小为n的数组有2的n次方个子集,这个是怎么来的呢,我们举个例子,对于一个大小为3的数组,他的子集应该有8个,我们用1代表当前元素在子集中,0表示不在,也就是 000,001,010,011,100,101,110,111,有没有发现,将上述所有元素看作2进制,转化过来就是0,1,2,3,4,5,6,7了,那么枚举数字代表状态即可

代码

class Solution {
    public List> subsets(int[] nums) {
        int x=nums.length;
        int u=1<>ans=new ArrayList<>();
        for(int i=0;i<=u;i++){
            Listbrr =new ArrayList<>();
            for(int j=0;j

17. 电话号码的字母组合

题意

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

题解

跟第一题深度相似,我们dfs的时候带入当前节点的位置,然后还是每个节点都去枚举所有的数据,停止条件是超出数组范围

代码


import java.util.*;


public class Solution {
    public static void main(String[] args) {
        int []nums={1,2,3};
    
    }
    public List letterCombinations(String digits) {
        
        Listarr=new ArrayList<>();
        arr.add("");
        arr.add("");
        arr.add("abc");
        arr.add("def");
        arr.add("ghi");
        arr.add("jkl");
        arr.add("mno");
        arr.add("pqrs");
        arr.add("tuv");
        arr.add("wxyz");
        Listans=new ArrayList<>();
        if(digits.length()==0){
        
            return ans;
        }
        char []brr=digits.toCharArray();
        char []crr=new char[brr.length];
        dfs(ans,brr,arr,crr,0);
        
        return ans;
    }
    public static void dfs(Listans,char []brr,Listarr,char []crr,int x){
        if(x>=brr.length){
            String s="";
            for(int i=0;i

39. 组合总和

题意

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

题解

本来没想到怎么做,翻了一下题解,发现是剪枝dfs,那就是跟之前的做法一样了,也就是每次从头开始深度搜索元素,当和大于target的时候停止即可

代码


import java.util.*;


public class Solution {
    public static void main(String[] args) {
        int []nums={1,2,3};

    }
    static List>ans;
    public List> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        int []arr=new int[target+1];
        ans=new ArrayList<>();
        dfs(arr,0,target,0,candidates);
        return ans;
    }
    public static void dfs(int []arr,int x,int y,int j,int []crr){
        if(x>y){
            return;
        }
        else if(x==y){
            Listbrr=new ArrayList<>();
            for(int i=0;i

22. 括号生成

题意

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

题解

如果你不会判断括号序列,请看题主的之前的栈篇,我们还是通过子集枚举,枚举所有的左端括号的位置,用1代替,0代替右边括号,最后看看是不是括号序列即可

代码


import java.util.*;


public class Solution {
    public static void main(String[] args) {
        int []nums={1,2,3};
        generateParenthesis(3);
    }
    public static int getx(int y){
        int sum=0;
        while(y>0){
            if((y&1)!=0){
                sum++;
            }
            y>>=1;
        }
        return sum;
    }
    public static List generateParenthesis(int n) {

        n=n*2;
        int u =1<ans=new ArrayList<>();
        for(int i=0;i<=u;i++){
            int z=i;
            if(getx(z)==n/2){
                String s="";
                for(int j=0;j<=n-1;j++){
                    int f=1< stack =new LinkedList<>();
        for(int i=0;i

79. 单词搜索

题意

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

题解

也是比较板子的题目,我们先建立个数组代表走的四个方向,然后继续建立数组代表当前位置来没有来过,那么我们进行dfs,看看每一个位置能不能对应上当前的字符串的位置,如果对应上,标记走过,继续向下dfs,如果不可以就停止,结束条件是超过字符串长度

代码


import java.util.*;


public class Solution {
    public static void main(String[] args) {
        char arr[][]={{'A','B','C','E'},{'S','F','C','S'},
                {'A','D','E','E'}
        };
        String s="ABCB";
        exist(arr,s);

    }
    static int n;
    static int m;
    static int mark[][]=new int[20][20];
    static boolean ans=false;
    static int []zou1={0,1,-1,0,0};
    static int []zou2={0,0,0,1,-1};
    public static boolean exist(char[][] board, String word) {
        n=board.length;
        m=board[0].length;
        char []s=word.toCharArray();
        for(int i=0;i=s.length){
            ans=true;
        }
        if(ans){
            return;
        }
        for(int i1=1;i1<=4;i1++){

                int x1=i+zou1[i1];
                int y1=j+zou2[i1];
                if(x1<0||x1>=n||y1<0||y1>=m||mark[x1][y1]==1){
                    continue;
                }
                if(board[x1][y1]==s[wei]){
                    mark[x1][y1]=1;
                    dfs(x1,y1,wei+1,s,board);
                    mark[x1][y1]=0;
                }

        }
    }



}

131. 分割回文串

题意

给你一个字符串 s,请你将 s 分割成一些 子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

题解

额,枚举最后结束字符的位置即可,子集枚举

举例 aabb,当前二进制如果为0101,那么就是aa  bb,如果是1111,就是a  a   b  b ,然后判断是不是回文即可

代码        


import java.util.*;


public class Solution {
    public static void main(String[] args) {
        int []nums={1,2,3};
        String s="aab";
        partition(s);

    }

    public static List> partition(String s) {
        List>ans=new ArrayList<>();
        char []brr=s.toCharArray();
        int n=s.length();
        int u=1<crr=new ArrayList<>();
            for(int j=0;j

51. N 皇后

题意

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

题解

作为hard题并没有hard题的难度

首先我们看看规则,每一行不可以有超过两个,但是至少一个,那么你可以提前把这些状态找出来,肯定是2 4 8 16 ...... 换成二进制就是 00001 00010 00100 ,01000,10000,然后你每次dfs,每一行的状态就从当前里面取出来就可以了,但是还有一个情况,怎么满足斜着也没有,你会发现,如果是沿着y=x的方向的话,他的x-y的差值是固定的,相同,沿着y=-x的方向,y+x的和是相同的,最后枚举出状态判断一下即可

代码


import java.util.*;


public class Solution {
    public static void main(String[] args) {
        int []nums={1,2,3};
        solveNQueens(4);

    }
    static int[]arr={1,2,4,8,16,32,64,128,256,512,1024,2048};
    static int x=0;
    public static  List> solveNQueens(int n) {
        x=n;
        int []mark=new int[20];
        List>ans=new ArrayList<>();
        int []brr=new int[20];
        dfs(ans,1,brr,mark);

        return ans;
    }

    public static int getx(int y){
        int sum=0;
        while(y!=1){
            sum++;
            y>>=1;
        }
        return sum;
    }

    public static void dfs(List>ans,int wei,int []brr,int []mark){
        if(wei>x){
            HashMapa=new HashMap<>();
            HashMapb=new HashMap<>();
            HashMapc=new HashMap<>();
            for(int i=1;i<=x;i++){
                if(a.containsKey(brr[i])){
                    return;
                }
                a.put(brr[i],1);
                int f=brr[i];
                int f1=getx(f);
                if(b.containsKey(i+f1)){
                    return;
                }
                b.put(i+f1,1);

                f=brr[i];
                f1=getx(f);
                if(c.containsKey(i-f1)){
                    return;

                }
                c.put(i-f1,1);

            }
            Listcrr=new ArrayList<>();
            for(int i=1;i<=x;i++){
                String s="";
                for(int j=1;j<=x;j++){
                    int f=1<

如果有不理解的可以问题主

你可能感兴趣的:(LeetCode,Hot100,题解,leetcode,算法,职场和发展)