0
点赞
收藏
分享

微信扫一扫

算法问题——动态规划和回溯算法问题


回溯算法

树形问题

排列问题

组合问题

二位平面的回溯算法

回溯递归问题

树形问题

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. 全排列

这个是不需要的处重复的

@Test
    public void test2(){
        ArrayList<ArrayList<Integer>> lists = permute(new int[]{1, 2, 3});
        for (List<Integer> list : lists) {
            for (int i : list) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }

    public ArrayList<ArrayList<Integer>> permute(int[] num) {
        ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
        boolean[] vis = new boolean[num.length];
        test11(num, 0, vis, list, lists);
        return lists;
    }

    private void test11(int[] num, int index, boolean[] vis, ArrayList<Integer> list, ArrayList<ArrayList<Integer>> lists) {
        if (index == num.length) {
            lists.add(new ArrayList<>(list));
            return;
        } else {
            for (int i = 0; i < num.length; i++) {
                if (!vis[i]) {
                    vis[i]=true;
                    list.add(num[i]);
                    test11(num,index+1,vis,list,lists);
                    list.remove(list.size()-1);
                    vis[i]=false;
                } else {
                    continue;
                }
            }
        }
    }

/**
 * 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

/**
     * 采用的是结果去重的方法
     *
     * @param nums
     * @return
     */
    public List<List<Integer>> permuteUnique2(int[] nums) {
        List<List<Integer>> lists = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        boolean[] vis = new boolean[nums.length];
        test2(nums, 0, vis, list, lists);
        lists = new ArrayList<>(new HashSet<>(lists));
        return lists;
    }

    private void test2(int[] nums, int index, boolean[] vis, List<Integer> list, List<List<Integer>> lists) {
        if (index == nums.length) {
            lists.add(new ArrayList<>(list));
            return;
        } else {
            for (int i = 0; i < nums.length; i++) {
                if (!vis[i]) {
                    list.add(nums[i]);
                    vis[i] = true;
                    test2(nums, index + 1, vis, list, lists);
                    list.remove(list.size() - 1);
                    vis[i] = false;
                } else {
                    continue;
                }
            }
        }
    }

/**
 * Copyright (C), 2018-2020
 * FileName: Permutation2
 * Author:   xjl
 * Date:     2020/7/15 16:21
 * Description: quanpailie
 */
package DFS_BFS;

import org.junit.Test;

import java.util.ArrayList;

public class Permutation2 {

    public ArrayList<String> Permutation(String str) {
        char[] array = str.toCharArray();
        ArrayList<String> result = new ArrayList<>();
        slove(array, result, 0, str.length());
        return result;
    }

    private void slove(char[] array, ArrayList<String> result, int index, int length) {
        if (index == length - 1) {
            String res = chage(array);
            result.add(res);
        } else {
            //说明要去确定indxd的位置
            for (int i = index; i < length; i++) {
                char temp = array[i];
                array[i] = array[index];
                array[index] = temp;
                //那么就是递归的调用到洗衣歌位置的字符
                slove(array, result, index + 1, length);
                //为了消除递归的时候的进行的交换的字符的影响
                temp = array[i];
                array[i] = array[index];
                array[index] = temp;
            }
        }
    }

    private String chage(char[] array) {
        StringBuilder res = new StringBuilder();
        for (char value : array) {
            res.append(value);
        }
        return res.toString();
    }

    public int reletive_7 (int[] digit) {
       String Str="";
       for (int i=0;i<digit.length;i++){
           Str+=String.valueOf(digit[i]);
       }
        ArrayList<String> list = Permutation(Str);
        int[] result=new int[list.size()];
        for (int i=0;i<result.length;i++){
            result[i]=Integer.valueOf(list.get(i));
        }
        int count=0;
        for (int i=0;i<result.length;i++){
            if (result[i]%7==0){
                count++;
            }
        }
        return count;
    }
    @Test
    public void test(){
        int[] arr={1,1,2};
        int result = reletive_7(arr);
        System.out.println(result);
    }
}

组合问题

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;
    }
}

举报

相关推荐

0 条评论