递归算法与回溯算法(leetcode的解题)

回溯算法

树形问题

排列问题

组合问题

二位平面的回溯算法

回溯递归问题



树形问题

17. 电话号码的字母组合(全排列的问题)

/**
 * Copyright (C), 2018-2020
 * FileName: letterCombinations
 * Author:   xjl
 * Date:     2020/3/20 15:30
 * Description: 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。  给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
 */
package Leetcode_Medium_difficulty;

import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 这里是一个递归问题的概念
 */
public class letterCombinations2 {
    Map<Character, String> map = new HashMap<Character, String>() {{
        put('2', "abc");
        put('3', "def");
        put('4', "ghi");
        put('5', "jkl");
        put('6', "mno");
        put('7', "pqrs");
        put('8', "tuv");
        put('9', "wxyz");
    }};
    //用于存储结构的list
    List<String> output = new ArrayList<String>();

    public void findCombination(String str, int index, String s) {
        //递归终止的条件
        if (index == str.length()) {
            output.add(s);
            return;
        }
        //递归
        char c = str.charAt(index);
        if (c >= '0' && c <= '9') {
            String letter = map.get(c);
            for (int i = 0; i < letter.length(); i++) {
                findCombination(str, index + 1, s + letter.charAt(i));
            }
        }
        return;
    }

    public List<String> letterCombinations(String digits) {
        if (digits .equals("")) {
            return output;
        }
        findCombination(digits, 0, "");
        return output;
    }

    @Test
    public void test() {
        System.out.println(letterCombinations("9").toString());
    }

}

93. 复原IP地址

131. 分割回文串

46. 全排列

/**
 * Copyright (C), 2018-2020
 * FileName: Permutation46
 * Author:   xjl
 * Date:     2020/4/23 14:53
 * Description: 全排列的组合
 */
package Leetcode_Medium_difficulty;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class Permutation46 {
    List<List<Integer>> lists = new ArrayList<>();
    Boolean[] used;

    public void generatepermuation(int[] nums, int index, List<Integer> list) {
        //递归的终止
        if (index == nums.length) {
            lists.add(new ArrayList<>(list));
            return;
        }
        //递归
        for (int i = 0; i < nums.length; i++) {
            if (!used[i]) {
                list.add(nums[i]);
                used[i] = true;
                generatepermuation(nums, index + 1, list);
                list.remove(list.size()-1);
                used[i] = false;
            }
        }
        return;
    }

    public List<List<Integer>> permute(int[] nums) {
        System.out.println(nums.length);
        if (nums.length == 0) {
            return lists;
        }
        List<Integer> list = new ArrayList();
        used = new Boolean[nums.length];
        for (int i = 0; i < nums.length; i++) {
            used[i] = false;
        }
        generatepermuation(nums, 0, list);
        return lists;
    }

    @Test
    public void test() {
        int[] numbers={1,2,3};
        System.out.println(permute(numbers).toString());
    }
}

排列问题

47. 全排列 II

组合问题

77. 组合

/**
 * Copyright (C), 2018-2020
 * FileName: combine
 * Author:   xjl
 * Date:     2020/4/23 18:29
 * Description: 组合
 */
package Leetcode_Medium_difficulty;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class combine {
    List<List<Integer>> lists = new ArrayList<>();

    public void generCombinations(int n, int k, int start, List<Integer> list) {
        //递归的结束的条件
        if (list.size() == k) {
            lists.add(new ArrayList<>(list));
            return;
        }
        for (int i = start; i <= n; i++) {
            list.add(i);
            generCombinations(n, k, i + 1, list);
            //回溯的过程
            list.remove(list.size() - 1);
        }
    }

    public List<List<Integer>> combine(int n, int k) {
        if (n <= 0 || k <= 0 || k > n) {
            return lists;
        }
        List<Integer> list = new ArrayList<>();
        generCombinations(n, k, 1, list);
        return lists;
    }

    @Test
    public void test() {
        System.out.println(combine(4, 2).toString());
    }
}

39. 组合总和

40. 组合总和 II

216. 组合总和 III

78. 子集

90. 子集 II

401. 二进制手表

二位平面的回溯算法

79. 单词搜索

/**
 * Copyright (C), 2018-2020
 * FileName: exist
 * Author:   xjl
 * Date:     2020/4/24 8:48
 * Description: 回溯算法的二维平面
 */
package Leetcode_Medium_difficulty;

import org.junit.Test;

public class exist {
    //四个方向
    int[][] d = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    int m, n;
    boolean[][] visit = new boolean[m][n];

    public boolean exist(char[][] board, String word) {
        m = board.length;
        n = board[0].length;
        //赋值没有访问过
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                visit[i][j] = false;
            }
        }
        //开始遍历
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (searchword(board, word, 0, i, j)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean searchword(char[][] board, String word, int index, int startx, int starty) {
        //递归的终止条件
        if (index == word.length() - 1) {
            return board[startx][starty] == word.charAt(index);
        }
        //递归的流程
        if (board[startx][starty] == word.charAt(index)) {
            visit[startx][starty] = true;
            //从四个方向开始往下寻找
            for (int i = 0; i < 4; i++) {
                int newx = startx + d[i][0];
                int newy = starty + d[i][1];
                if (inArea(newx, newy) && !visit[newx][newy]) {
                    if (searchword(board, word, index + 1, newx, newy)) {
                        return true;
                    }
                }
            }
            visit[startx][starty] = false;
        }
        return false;
    }

    //判断是否在矩阵中
    private boolean inArea(int newx, int newy) {
        return newx >= 0 && newx < m && newy >= 0 && newy < n;
    }

    @Test
    public void test() {

    }
}

回溯递归问题

public class exist79 {
    //四个方向
    int[][] d = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    int m, n;
    boolean[][] visit;

    public boolean exist(char[][] board, String word) {
        m = board.length;
        n = board[0].length;
        //赋值没有访问过
        visit=new boolean[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                visit[i][j] = false;
            }
        }
        //开始遍历
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (searchword(board, word, 0, i, j)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean searchword(char[][] board, String word, int index, int startx, int starty) {
        //递归的终止条件
        if (index == word.length() - 1) {
            return board[startx][starty] == word.charAt(index);
        }
        //递归的流程
        if (board[startx][starty] == word.charAt(index)) {
            visit[startx][starty] = true;
            //从四个方向开始往下寻找
            for (int i = 0; i < 4; i++) {
                int newx = startx + d[i][0];
                int newy = starty + d[i][1];
                if (inArea(newx, newy) && !visit[newx][newy]) {
                    if (searchword(board, word, index + 1, newx, newy)) {
                        return true;
                    }
                }
            }
            visit[startx][starty] = false;
        }
        return false;
    }

    //判断是否在矩阵中
    private boolean inArea(int newx, int newy) {
        return newx >= 0 && newx < m && newy >= 0 && newy <n;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41605937/article/details/105706248
今日推荐