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