一、没有重复项数字的全排列
给出一组数字,返回该组数字的所有排列
例如:
[1,2,3]的所有排列如下
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1].
(以数字在数组中的位置靠前为优先级,按字典序排列输出。)
数据范围:数字个数 0<n≤6
要求:空间复杂度 O(n!),时间复杂度 O(n!)
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param num int整型一维数组
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> permute (int[] num) {
// write code here
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
dfs(num, res, new ArrayList<>(), 0);
return res;
}
void dfs(int[] num, ArrayList<ArrayList<Integer>> res, ArrayList<Integer> t,
int index) {
if (t.size() == num.length) {
res.add(new ArrayList<>(t));
return;
}
for (int i = 0; i < num.length; i++) {
if (t.contains(num[i])) {
continue;
}
t.add(num[i]);
dfs(num, res, t, i + 1);
t.remove(t.size() - 1);
}
}
}
运行结果

二、有重复项数字的全排列
给出一组可能包含重复项的数字,返回该组数字的所有排列。结果以字典序升序排列。
数据范围: 0<n≤8 ,数组中的值满足 −1≤val≤5
要求:空间复杂度 O(n!),时间复杂度 O(n!)
import java.util.*;
public class Solution {
ArrayList<ArrayList<Integer>> list = new
ArrayList<>(); // 存最终全排列结果
ArrayList<Integer> tmp = new ArrayList<>(); // 当前排列结果
Set<Integer> set = new
HashSet<>(); // 存已用数组元素的下标,防重复
public ArrayList<ArrayList<Integer>> permuteUnique (int[] num) {
Arrays.sort(num); // 升序
dfs(num); // 调用 dfs
return list;
}
// dfs
public void dfs(int[] nums) {
if (tmp.size() == nums.length) {
ArrayList<Integer> t = new ArrayList<>(tmp);
if (!list.contains(t)) list.add(
t); // 由于元素可能重复,导致排列可能重复,要判断一下
return;
}
for (int i = 0; i < nums.length; i++) {
if (set.contains(i)) continue; // 下标重复
tmp.add(nums[i]);
set.add(i);
dfs(nums); // 排列数组下个元素
tmp.remove(tmp.size() - 1); // 回溯
set.remove(i);
}
}
}
运行结果

三、岛屿数量
给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。
岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。
例如:
输入
[
[1,1,0,0,0],
[0,1,0,1,1],
[0,0,0,1,1],
[0,0,0,0,0],
[0,0,1,1,1]
]
对应的输出为3
(注:存储的01数据其实是字符'0','1')
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 判断岛屿数量
* @param grid char字符型二维数组
* @return int整型
*/
public int solve (char[][] grid) {
//递归找
int x = grid.length;
int y = grid[0].length;
int res = 0;
int [][] moveGrid = new int[4][2]; //右下左上
moveGrid[0] = new int[] {0, 1};
moveGrid[1] = new int[] {1, 0};
moveGrid[2] = new int[] {0, -1};
moveGrid[3] = new int[] {-1, 0};
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
char element = grid[i][j];
if (element == '1') {
recircleSearch(grid, i, j, moveGrid);
res++;
}
}
}
return res;
}
public void recircleSearch(char[][] grid, int i, int j, int[][]moveGrid) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length) return;
if (grid[i][j] == '0' || grid[i][j] == 'x') return ;
grid[i][j] = 'x';
for (int k = 0; k < 4; k++) {
recircleSearch(grid, i + moveGrid[k][0], j + moveGrid[k][1], moveGrid);
}
}
}
运行结果

四、字符串的排列
输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。

import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param str string字符串
* @return string字符串ArrayList
*/
public ArrayList<String> Permutation (String str) {
ArrayList<String> res = new ArrayList<>();
char[] chars = str.toCharArray();
Arrays.sort(chars);
boolean[] visited = new boolean[chars.length];
dfs(chars, res, new StringBuilder(), visited);
return res;
}
void dfs(char[] chars, ArrayList<String> res, StringBuilder tmp,
boolean[] visited) {
if (chars.length == tmp.length()) {
res.add(new String(tmp));
return;
}
for (int i = 0; i < chars.length; i++) {
if (visited[i]) {
continue;
}
if (i > 0 && chars[i] == chars[i - 1] && !visited[i - 1]) {
continue;
}
tmp.append(chars[i]);
visited[i] = true;
dfs(chars, res, tmp, visited);
visited[i] = false;
tmp.deleteCharAt(tmp.length() - 1);
}
}
}
运行结果

五、N皇后问题
N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后,
要求:任何两个皇后不同行,不同列也不在同一条斜线上,
求给一个整数 n ,返回 n 皇后的摆法数。
数据范围: 1≤n≤9
要求:空间复杂度 O(n) ,时间复杂度 O(n!)

import java.util.*;
public class Solution {
int ans = 0;
//分别对应竖向标记,左下角标记,右下角标记,数组长度跟据n的最大范围囊括一下即可
boolean[] b = new boolean[100]; //y
boolean[] c = new boolean[100]; //x + y - 1
boolean[] d = new boolean[100]; //x - y + n
public int Nqueen (int n) {
//一定要从1开始,否则会出现数组越界(如-1)
dfs(1, n);
return ans;
}
public void dfs(int x, int n) {
if (x > n) {
ans++;
return;
}
for (int y = 1; y <= n; y++) {
if (!b[y] && !c[x + y - 1] && !d[x - y + n]) {
b[y] = true;
c[x + y - 1] = true;
d[x - y + n] = true;
dfs(x + 1, n);
b[y] = false;
c[x + y - 1] = false;
d[x - y + n] = false;
}
}
}
}
运行结果

六、括号生成
给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。
例如,给出n=3,解集为:
"((()))", "(()())", "(())()", "()()()", "()(())"
import java.util.*;
public class Solution {
public ArrayList<String> generateParenthesis(int n) {
ArrayList<String> res = new ArrayList<>();
dfs(res, new char[n * 2], 0, 0);
return res;
}
private void dfs(List<String> res, char[] arr, int l, int r) {
int n = arr.length, idx = l + r;
if (idx == n) {
res.add(new String(arr));
}
if (l < n / 2) {
arr[idx] = '(';
dfs(res, arr, l + 1, r);
}
if (l != r) {
arr[idx] = ')';
dfs(res, arr, l, r + 1);
}
}
}
运行结果

七、矩阵最长递增路径
给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。
这个路径必须满足以下条件:
1. 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。
2. 你不能走重复的单元格。即每个格子最多只能走一次。
数据范围:1≤n,m≤1000,0≤matrix[i][j]≤1000
进阶:空间复杂度 O(nm) ,时间复杂度 O(nm)

import java.util.*;
public class Solution {
public int solve(int[][] matrix) {
int res = 0, m = matrix.length, n = matrix[0].length;
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
res = Math.max(res, dfs(dp, matrix, i, j, -1));
}
}
return res;
}
private int dfs(int[][] dp, int[][] grid, int i, int j, int min) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length ||
grid[i][j] <= min) {
return 0;
}
if (dp[i][j] == 0) {
int res = 1;
res = Math.max(res, dfs(dp, grid, i - 1, j, grid[i][j]) + 1);
res = Math.max(res, dfs(dp, grid, i + 1, j, grid[i][j]) + 1);
res = Math.max(res, dfs(dp, grid, i, j - 1, grid[i][j]) + 1);
res = Math.max(res, dfs(dp, grid, i, j + 1, grid[i][j]) + 1);
dp[i][j] = res;
}
return dp[i][j];
}
}
运行结果

321



被折叠的 条评论
为什么被折叠?



