1. One-dimensional problem
1) Permutation problem (leetCode 46)
Problem description: Input the numbers 1, 2, 3, and output all their combinations 1 2 3 , 1 3 2, 2 1 3, 2 3 1, 3 1 2, 3 2 1 .
Code:
method one:
Use index to mark the length of the temp array, and stop when the length is 3.
Each for loop starts from 0, but the value that has been taken is marked with flag.
class HuiSu{
static ArrayList<ArrayList<Integer>> res = new ArrayList<>();
static ArrayList<Integer> temp = new ArrayList<>();
public static void main(String[] args) {
int[] nums = {1,2,3};
int[] flag = new int[nums.length];
helper(nums,0,flag);
System.out.println(res);
}
//第一种方式
public static void helper(int[] nums,int index,int[] flag){
if(index==nums.length){ //通过index来标记temp数组的长度,当长度到达3的时候就停止
res.add(new ArrayList<>(temp));
}
for(int i=0;i<nums.length;i++){ //注意这里的i是从0开始
if(flag[i]==0){
flag[i] = 1;
temp.add(nums[i]);
helper(nums,index+1,flag);//通过index来标记temp数组的长度,当长度到达3的时候就停止
temp.remove(temp.size()-1);
flag[i] = 0;
}
}
}
}
The second method is to directly take out the length of the array without using the index tag, and stop when the length is 3.
class HuiSu{
static ArrayList<ArrayList<Integer>> res = new ArrayList<>();
static ArrayList<Integer> temp = new ArrayList<>();
public static void main(String[] args) {
int[] nums = {1,2,3};
int[] flag = new int[nums.length];
helper(nums,flag);
System.out.println(res);
}
//第二种方式
public static void helper(int[] nums,int[] flag){
if(temp.size()==nums.length){
res.add(new ArrayList<>(temp));
}
for(int i=0;i<nums.length;i++){
if(flag[i]==0){
flag[i] = 1;
temp.add(nums[i]);
helper(nums,flag);
temp.remove(temp.size()-1);
flag[i] = 0;
}
}
}
}
2) Combination problems
Title description: Select all combinations of k numbers from n numbers 1...n (leetCode question 77)
Code:
class HuiSu{
static ArrayList<ArrayList<Integer>> res = new ArrayList<>();
static ArrayList<Integer> temp = new ArrayList<>();
public static void main(String[] args) {
int[] nums = {1,2,3,4};
int start = 0;
int index = 1;
int k = 2;
int n = 4;
int[] flag = new int[nums.length];
helper(index,n,k);
System.out.println(res);
}
public static void helper(int index,int n,int k){
if(temp.size()==2){
res.add(new ArrayList<>(temp));
}
for(int i=index;i<=n;i++){
temp.add(i);
helper(i+1,n,k); //这边使用i + 1还是index + 1
temp.remove(temp.size()-1);
}
}
}
3) Given a numeric keypad, enter a numeric string, and return all possible letter combinations .
Through this question, the understanding of index has been deepened. The difference between index and i, where i is increasing, but index is 0 at the beginning, and then 1.
class HuiSu {
public static void main(String[] args) {
Solution s = new Solution();
s.letterCombinations("23");
}
}
class Solution {
ArrayList<Character> temp = new ArrayList<>();
ArrayList<ArrayList<Character>> res = new ArrayList<>();
public void letterCombinations(String digits) {
String[] keyboard = new String[] { " ", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
helper(keyboard, 0, digits);
System.out.println(res);
}
public void helper(String[] keyboard, int index, String digits) {
//这个停止条件
if (index == digits.length()) {
res.add(new ArrayList<Character>(temp));
return;
} //其实这题和[1,2,3]的排列相比也就多了这行
String letters = keyboard[digits.charAt(index) - '0']; // 首先letter = "abc" 第二次letter = "def"
for(int i=0;i<letters.length();i++){
temp.add(letters.charAt(i));
helper(keyboard,index+1,digits);
temp.remove(temp.size()-1);
}
}
}
4) Convinced topics
Given an array, find the combination of numbers in the array that add up to 100
class HuiSu {
static ArrayList<Integer> temp = new ArrayList<>();
static ArrayList<ArrayList<Integer>> result = new ArrayList<>();
static int[] visit;
public static void main(String[] args) {
int[] nums = {64,50,32,16,8,4,2,1,96};
int[] flag = new int[nums.length]; //用来标记已经访问过的坐标
helper(nums,100,0,flag);
System.out.println(result);
}
public static void helper(int[] nums,int target,int index,int[] flag){
if(target==0){
result.add(new ArrayList<>(temp));
}
if(index>=nums.length||target<0)
return;
for(int i=index;i<nums.length;i++){
//if(flag[index]==0){ //没有必要加上标志位
//flag[i] = 1;
temp.add(nums[i]);
helper(nums,target-nums[i],i+1,flag);
temp.remove(temp.size()-1);
//flag[i] = 0;
//}
}
}
}
5) A path that sums to a certain value in a binary tree
Input the root node of a binary tree and an integer, and print out all paths in the binary tree whose sum of node values is the input integer. A path is defined as a path from the root node of the tree down to the nodes passed by the leaf nodes. (Note: In the list of returned values, the array with the largest array length comes first)
Code:
class Solution {
ArrayList<ArrayList<Integer>> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
if(root==null||target<0)
return list1;
list2.add(root.val); //这两行代码的位置也有讲究
target = target - root.val; //这两行代码的位置也有讲究
if(root.left==null&&root.right==null&&target==0){
list1.add(new ArrayList(list2));
//return list1; //这一行代码也不能要,否则后面的list2.remove(list2.size()-1)无法执行
}
FindPath(root.left,target);
FindPath(root.right,target);
list2.remove(list2.size()-1);
return list1;
}
}
important point:
Draw a tree of nodes here, it will be clear.
list2.add(root.val); //这两行代码的位置也有讲究
target = target - root.val; //这两行代码的位置也有讲究
//return list1; //这一行代码也不能要,否则后面的
2. Two-dimensional problem
1) The range of motion of the robot
There is a square with m rows and n columns on the ground. A robot starts to move from the grid of coordinates 0 and 0, and can only move one grid in four directions: left, right, up and down at a time, but cannot enter the grid where the sum of the digits of the row and column coordinates is greater than k. For example, when k is 18, the robot is able to enter square (35,37) because 3+5+3+7 = 18. However, it cannot go into square (35,38) because 3+5+3+8 = 19. How many squares can the robot reach?
Code:
class Solution {
int count;
public int movingCount(int threshold, int rows, int cols) //row行号,cols列号
{
int[][] flag = new int[rows][cols];
Helper(threshold,rows,cols,0,0,flag);
return count;
}
public void Helper(int threshold,int rows,int cols,int i,int j,int[][] flag){
if(i<0||i>=rows||j<0||j>=cols||flag[i][j]==1||f(i)+f(j)>threshold){
return;
}
flag[i][j] = 1;
count++;
Helper(threshold,rows,cols,i+1,j,flag);
Helper(threshold,rows,cols,i-1,j,flag);
Helper(threshold,rows,cols,i,j+1,flag);
Helper(threshold,rows,cols,i,j-1,flag);
}
public int f(int num){
int result = 0;
while(num>0){
result += num%10;
num /= 10;
}
return result;
}
}
Thinking: It will not work to replace the following three lines, because some grids satisfy f(i)+f(j)<=threshold, but the robot cannot walk, such as 1Xn grids, some grids satisfy the constraints, but the robot cannot pass .
if(i<0||i>=rows||j<0||j>=cols||flag[i][j]==1{
return;
}
flag[i][j] = 1;
if(f(i)+f(j)<=threshold)
count++;
2) floodfill problem
There is a 2D map composed of 1 and 0, 0 means water, 1 means land, and ask how many land is surrounded by water.
Idea: Use a matrix of the same size as the sign matrix, and set the corresponding bit in the sign matrix to 1 every time the path traveled, indicating that it has been passed and will not go again.
Code:
public class HuiSu {
private static int[][] array = {
{1, 1, 0, 0, 1},
{1, 1, 0, 0, 0},
{0, 0, 1, 0, 1},
{0, 0, 0, 1, 1},
};
public static void main(String[] args) {
int maxLine = 5; //列
int maxRow = 4; //行
int[][] flag = new int[maxRow][maxLine];
int countNum = 0;
for(int i=0;i<maxRow;i++){
for(int j=0;j<maxLine;j++){
if(array[i][j]==1&&flag[i][j]==0){
helper(i,j,maxRow,maxLine,flag);
countNum++;
}
}
}
System.out.println(countNum);
}
public static void helper(int i,int j,int maxRow,int maxLine,int[][] flag){
if(i<0||i>=maxRow||j<0||j>=maxLine)
return;
if(array[i][j]==1&&flag[i][j]==0){
flag[i][j]=1;
helper(i+1,j,maxRow,maxLine,flag);
helper(i-1,j,maxRow,maxLine,flag);
helper(i,j+1,maxRow,maxLine,flag);
helper(i,j-1,maxRow,maxLine,flag);
}
}
3) Maze problem
public class HuiSu {
static int count = 0;
/**
* 定义迷宫数组
*/
private static int[][] array = {
{0, 0, 1, 0, 0, 0, 1, 0},
{0, 0, 1, 0, 0, 0, 1, 0},
{0, 0, 1, 0, 1, 1, 0, 1},
{0, 1, 1, 1, 0, 0, 1, 0},
{0, 0, 0, 1, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 1, 0, 1},
{0, 1, 1, 1, 1, 0, 0, 1},
{1, 1, 0, 0, 0, 1, 0, 1},
{1, 1, 0, 0, 0, 0, 0, 0}
};
public static void main(String[] args) {
int maxLine = 8; //列
int maxRow = 9; //行
System.out.println("开始时间: "+System.currentTimeMillis());
int[][] flag = new int[maxRow][maxLine];
helper(0,0,maxRow,maxLine,flag);;
System.out.println("结束时间: "+System.currentTimeMillis());
}
public static void helper(int i,int j,int maxRow,int maxLine,int[][] flag){
//如果没有找到就继续
if(i<0||i>=maxRow||j<0||j>=maxLine||array[i][j]==1||array[i][j]==5){
return;
}
if(i==maxRow-1&&j==maxLine-1){
print(maxRow,maxLine); //将能到达目的的路径打印出来
return;
}
array[i][j] = 5; //已经走过的路径设置为5
helper(i-1,j,maxRow,maxLine,flag);
helper(i+1,j,maxRow,maxLine,flag);
helper(i,j+1,maxRow,maxLine,flag);
helper(i,j-1,maxRow,maxLine,flag);
array[i][j] = 0; //从坐标[i,j]开始,都不行,就清除标志
}
//打印
private static void print(int maxRow,int maxLine) {
System.out.println("得到第"+(++count)+"解");
for (int i = 0; i < maxRow; i++) {
for (int j = 0; j < maxLine; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
}
}