牛客top100 - 自刷打卡day7+8+9 - 递归回溯

文章提供了几个使用Java实现的递归与回溯算法的示例,包括无重复数字的全排列、有重复数字的全排列、岛屿数量计算、字符串排列、括号生成以及矩阵最长递增路径问题。这些算法主要涉及深度优先搜索策略,解决各种组合与路径寻找问题。
摘要由CSDN通过智能技术生成

递归/回溯

BM55

没有重复项数字的全排列

思路中等57.14%

  • 一般回溯排列/组合的时候习惯使用used数组标识数组是否被使用
  • 不过本题这里可以不适用这个,直接使用contains就能解决这个问题
import java.util.*;

public class Solution {
    public ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    public int[] used = null;
    public ArrayList<ArrayList<Integer>> permute(int[] num) {
        if (num == null) return res;
        ArrayList<Integer> list = new ArrayList<>();
        back(num,  list);
        return res;
    }
    public void back(int[] num,  ArrayList<Integer> list) {
        if (list.size() == num.length) {
            res.add(new ArrayList<>(list));
            return ;
        }
        for (int i = 0; i < num.length; i++) {
            if (list.contains(num[i])) {
                continue;
            } else {
                list.add(num[i]);
                back(num,  list);
                list.remove(list.size() - 1);
            }
        }
    }
}

BM56

有重复项数字的全排列

思路中等39.77%

  • 本题有重复项, 所以我们开始对数据进行排序, 由于这里的重复数字, 即使list中含有某一个数字, 但是num中的重复数字还是可以添加的, 所以使用used解决
import java.util.*;

public class Solution {
    public ArrayList<Integer> arrayList = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
        boolean[] used = new boolean[num.length];
        Arrays.sort(num);
        backing(num, used);
        return res;
    }
    public void backing(int[]num, boolean[] used) {
        if (arrayList.size() == num.length) {
            res.add(new ArrayList<>(arrayList));
            return ;
        }
        for (int i = 0; i < num.length; i++) {
            if (i > 0 && num[i - 1] == num[i] && used[i - 1] == false) {
                continue;
            }
            if (used[i] == false) {
                arrayList.add(num[i]);
                used[i] = true;
                backing(num, used);
                arrayList.remove(arrayList.size() - 1);
                used[i] = false;
            }
        }

    }
}

BM57

岛屿数量

思路中等41.81%

  • 深搜
import java.util.*;


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

BM58

字符串的排列

思路中等23.65%

import java.util.ArrayList;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Arrays;
import java.util.Set;
public class Solution {
    ArrayList<String> res = new ArrayList<>();
    String path = new String();
    public ArrayList<String> Permutation(String str) {
        if (str.length() <= 1) {

            res.add(str);
            return res;
        }
        char[] ch = str.toCharArray();
        Arrays.sort(ch);
        boolean[] used = new boolean[ch.length];
        back(ch, used);

        return res;

    }
    public void back(char[] ch, boolean[] used) {
        if (path.length() == ch.length) {
            res.add(path);
            return;
        }
        for (int i = 0; i < ch.length; i++) {
            //剪枝重复元素
            if (i > 0 && ch[i] == ch[i - 1] && used[i - 1] == false) {
                continue;
            }
            if (used[i] == false) {
                path += ch[i];
                used[i] = true;
                back(ch, used);
                path = path.substring(0, path.length() - 1);
                used[i] = false;
            }
        }
    }
}

BM59

N皇后问题

思路较难46.70%

N皇后, 过, 以后补

BM60

括号生成

思路中等54.95%

import java.util.*;


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

    }
}

BM61

矩阵最长递增路径

思路中等38.36%

import java.util.*;


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

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                max = Math.max(max, backing(matrix, i, j, -1));
            }
        }
        return max;
    }
    public int backing(int[][] arr, int i, int j, int pre) {
        if (arr[i][j] <= pre) {
            return 0;
        }
        int max = 0;
        //下
        if (i + 1 < arr.length) {
            max = Math.max(max, backing(arr, i + 1, j, arr[i][j]));
        }
        //上
        if (i >= 1) {
            max = Math.max(max, backing(arr, i - 1, j, arr[i][j]));
        }
        //左
        if (j - 1 >= 0) {
            max = Math.max(max, backing(arr, i, j - 1, arr[i][j]));
        }
        //右
        if (j + 1 < arr[0].length) {
            max = Math.max(max, backing(arr, i, j + 1, arr[i][j]));
        }
        return max + 1;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值