测试开发备战秋招面试12-牛客刷题之递归/回溯

努力了那么多年,回头一望,几乎全是漫长的挫折和煎熬。对于大多数人的一生来说,顺风顺水只是偶尔,挫折、不堪、焦虑和迷茫才是主旋律。我们登上并非我们所选择的舞台,演出并非我们所选择的剧本。继续加油吧!

目录

1、没有重复项数字的全排列

2、有重复项数字的全排列

3、岛屿数量

4、字符串的排列

5、N皇后问题

6、括号生成

7、 矩阵最长递增路径


1、没有重复项数字的全排列

题目链接:没有重复项数字的全排列_牛客题霸_牛客网

思路:递归全排列,回溯到首位元素。
Java版:

import java.util.*;

public class Solution {
    ArrayList<ArrayList<Integer>> list = new ArrayList<>() ;
    public ArrayList<ArrayList<Integer>> permute(int[] num) {
        LinkedList<Integer> lst = new LinkedList<>() ;
        dfs(lst, num) ;
        return list ;
    }
    public void dfs(LinkedList<Integer> lst, int [] num){
        if(num.length == lst.size()){
            list.add(new ArrayList<>(lst)) ;
            return ;
        }
        for(int i=0; i<num.length; i++){
            if(lst.contains(num[i])){
                continue ;
            }
            lst.add(num[i]) ;
            dfs(lst, num) ;
            lst.removeLast() ;

        }
    } 
}

2、有重复项数字的全排列

题目链接:有重复项数字的全排列_牛客题霸_牛客网

思路:也是递归+回溯,不过这次为了防止重复,用一个mark标记是否访问过,被访问过的跳过,或者当前元素和上一个元素相等且上一个元素未被访问,则跳过。

Java版:

import java.util.*;

public class Solution {
    ArrayList<ArrayList<Integer>> list = new ArrayList<>() ;
    public ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
        boolean [] mark = new boolean[num.length] ;
        Arrays.sort(num) ;
        LinkedList<Integer> lst = new LinkedList<>() ;
        dfs(lst, num, mark) ;
        return list ;
    }
    public void dfs(LinkedList<Integer> lst, int [] num, boolean [] mark){
        if(num.length == lst.size()){
            list.add(new ArrayList<>(lst)) ;
            return ;
        }
        for(int i=0; i<num.length; i++){
            if(mark[i] || (i>0 && num[i] == num[i-1] && mark[i-1])){
                continue ;
            }
            mark[i] = true ;
            lst.add(num[i]) ;
            dfs(lst, num, mark) ;
            lst.removeLast() ;
            mark[i] = false ;
        }
    }
}

3、岛屿数量

题目链接:岛屿数量_牛客题霸_牛客网

思路:搜索+标记,每轮搜索,岛屿数目加1,所有数字标记为0.

Java版:

import java.util.*;


public class Solution {
    /**
     * 判断岛屿数量
     * @param grid char字符型二维数组 
     * @return int整型
     */
    public int solve (char[][] grid) {
        // write code here
        int cnt = 0 ;
        for(int i=0; i<grid.length; i++){
            for(int j=0; j<grid[0].length; j++){
                if(grid[i][j] == '1'){
                    dfs(grid, i, j) ;
                    cnt ++ ;
                }
            }
        }
        return cnt ;
    }
    public void dfs(char [][] grid, int x, int y){
        if(x<0 || x>grid.length-1 || y<0 || y>grid[0].length -1 || grid[x][y] == '0'){
            return ;
        }
        grid[x][y] = '0' ;
        dfs(grid, x-1, y) ;
        dfs(grid, x+1, y) ;
        dfs(grid, x, y-1) ;
        dfs(grid, x, y+1) ;
    }
}

4、字符串的排列

题目链接:字符串的排列_牛客题霸_牛客网

思路:递归+回溯+标记+排序。

Java版:

import java.util.*;
public class Solution {
    ArrayList<String> list = new ArrayList<>() ;
    boolean [] mark ;
    public ArrayList<String> Permutation(String str) {
       mark = new boolean[str.length()] ;
       char [] c = str.toCharArray() ;
       Arrays.sort(c) ;
       StringBuilder sb = new StringBuilder("") ;
       dfs(str, c, sb) ;
       return list ;
    }
    public void dfs(String str, char [] c, StringBuilder sb){
        if(sb.length() == str.length()){
            list.add(sb.toString()) ;
            return ;
        }
        for(int i=0; i<str.length(); i++){
            if(mark[i] || (i>0 && !mark[i-1] && c[i-1] == c[i])){
                continue ;
            }
            mark[i] = true ;
            sb.append(c[i]) ;
            dfs(str, c, sb) ;
            sb.deleteCharAt(sb.length()-1) ;
            mark[i] = false ;
        }
    }
}

5、N皇后问题

题目链接:N皇后问题_牛客题霸_牛客网

思路:递归+回溯+三集合标记法
Java版:

import java.util.*;


public class Solution {
    /**
     * 
     * @param n int整型 the n
     * @return int整型
     */
     Set<Integer> s1 = new HashSet<>() ;
     Set<Integer> s2 = new HashSet<>() ;
     Set<Integer> s3 = new HashSet<>() ;
     int cnt = 0 ;
    public int Nqueen (int n) {
        // write code here
        dfs(0, n) ;
        return cnt ;
    }
    public void dfs(int i, int n){
        if(i == n){
            cnt ++ ;
            return ;
        }
        
        for(int j=0; j<n; j++){
            if(s1.contains(j) || s2.contains(i-j) || s3.contains(i+j)){
                continue ;
            }
            s1.add(j) ;
            s2.add(i-j) ;
            s3.add(i+j) ;
            dfs(i+1, n) ;
            s1.remove(j) ;
            s2.remove(i-j) ;
            s3.remove(i+j) ;
        }
        
    }
}

6、括号生成

题目链接:括号生成_牛客题霸_牛客网

思路:左括号数目小于n,拼左括号,右括号数目小于左括号且小于n,拼右括号,递归出口是左右括号的数目都等于n。
Java版:

import java.util.*;


public class Solution {
    /**
     * 
     * @param n int整型 
     * @return string字符串ArrayList
     */
    ArrayList<String> lsit = new ArrayList<>() ;
    public ArrayList<String> generateParenthesis (int n) {
        // write code here
        String s = new String("") ;
        dfs(0,0,n,s) ;
        return lsit ;
    }
    public void dfs(int left, int right, int n, String s){
        if(left==n && right==n){
            lsit.add(s) ;
            return ;
        }
        if(left<n){
            dfs(left+1, right, n, s+"(") ;
        }
        if(right<left && right<n){
            dfs(left, right+1, n, s+")") ;
        }
    }
}

7、 矩阵最长递增路径

题目链接:矩阵最长递增路径_牛客题霸_牛客网

思路:递归搜索递增路径,比较并找出所有递增路劲中的最大值。
Java版:
 

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 递增路径的最大长度
     * @param matrix int整型二维数组 描述矩阵的每个数
     * @return int整型
     */
    public int solve (int[][] matrix) {
        // write code here
        int max = 0 ;
        for(int i=0; i<matrix.length; i++){
            for(int j=0; j<matrix[0].length; j++){
                max = Math.max(max, dfs(matrix, i, j, -1)) ;
            }
        }
        return max ;
    }
    public int dfs(int [][]matrix, int i, int j, int pre){
        if(matrix[i][j] <= pre){
            return 0 ;
        }
        int max = 0 ;
        if(i>0){
            max = Math.max(max, dfs(matrix,i-1,j,matrix[i][j])) ;
        }
        if(j>0){
            max = Math.max(max, dfs(matrix,i,j-1,matrix[i][j])) ;
        }
        if(i<matrix.length-1){
            max = Math.max(max, dfs(matrix,i+1,j,matrix[i][j])) ;
        }
        if(j<matrix[0].length-1){
            max = Math.max(max, dfs(matrix,i,j+1,matrix[i][j])) ;
        }
        return max + 1 ;
    }
}

猜你喜欢

转载自blog.csdn.net/nuist_NJUPT/article/details/130816883