博客
关于我
java关于回溯算法的题1
阅读量:316 次
发布时间:2019-03-04

本文共 7834 字,大约阅读时间需要 26 分钟。

回溯算法与力扣题解

1. 组合总和

题目描述

给定一个无重复元素的数组 candidates 和一个目标数 target,找出 candidates 中所有可以使数字和为 target 的组合。数组中的数字可以无限制重复被选取。所有数字(包括 target)都是正整数。解集不能包含重复的组合。

示例

  • 输入:candidates = [2,3,6,7], target = 7 输出:[[7], [2,2,3]]
  • 输入:candidates = [2,3,5], target = 8 输出:[[2,2,2,2], [2,3,3], [3,5]]
  • 解题思路

    使用回溯算法,尝试所有可能的组合,排除重复的情况。通过排序和递归的方式,确保每个组合的元素不重复,并且总和等于目标。

    代码实现

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    public class Solution {
    public List
    > combinationSum(int[] candidates, int target) {
    List
    > result = new ArrayList<>();
    Arrays.sort(candidates);
    findAllCombination(result, candidates, target, 0, new ArrayList<>());
    return result;
    }
    private static void findAllCombination(List
    > result, int[] candidates, int target, int start, List
    path) { if (target < 0) { return; } if (target == 0) { if (!result.contains(path)) { result.add(new ArrayList<>(path)); } return; } for (int i = start; i < candidates.length; i++) { int num = candidates[i]; if (num > target) { continue; } if (path.contains(num)) { continue; } path.add(num); findAllCombination(result, candidates, target - num, i, path); path.remove(); if (target - num == 0) { return; } } } }

    2. 组合总和 II

    题目描述

    给定一个数组 candidates 和一个目标数 target,找出所有可以使数字和为 target 的组合。每个数字在每个组合中只能使用一次。

    示例

  • 输入:candidates = [10, 1, 2, 7, 6, 1, 5], target = 8 输出:[[1, 7], [1, 2, 5], [2, 6], [1, 1, 6]]
  • 输入:candidates = [2, 5, 2, 1, 2], target = 5 输出:[[1, 2, 2], [5]]
  • 解题思路

    使用回溯算法,确保每个数字在组合中只使用一次。通过排序和递归的方式,生成所有满足条件的组合。

    代码实现

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    public class Solution {
    public List
    > combinationSum2(int[] candidates, int target) {
    List
    > result = new ArrayList<>();
    Arrays.sort(candidates);
    findAllOnly(result, new ArrayList<>(), candidates, target, 0);
    return result;
    }
    private static void findAllOnly(List
    > result, List
    path, int[] candidates, int target, int start) { if (target < 0) { return; } if (target == 0) { if (!result.contains(path)) { result.add(new ArrayList<>(path)); } return; } for (int i = start; i < candidates.length; i++) { int num = candidates[i]; if (num > target) { continue; } if (path.contains(num)) { continue; } path.add(num); findAllOnly(result, path, candidates, target - num, i); path.remove(); } } }

    3. 组合总和 III

    题目描述

    找出所有相加之和为 nk 个数的组合。组合中只允许含有1-9的正整数,并且每种组合中不存在重复的数字。

    示例

  • 输入:k = 3, n = 7 输出:[[1, 2, 4]]
  • 输入:k = 3, n = 9 输出:[[1, 2, 6], [1, 3, 5], [2, 3, 4]]
  • 解题思路

    生成所有可能的1-9数组,然后使用回溯算法找出所有满足条件的组合。确保组合中数字不重复,且总和等于目标。

    代码实现

    import java.util.ArrayList;
    import java.util.List;
    public class Solution {
    public List
    > combinationSum3(int k, int n) {
    List
    > result = new ArrayList<>();
    int[] candidates = new int[9];
    for (int i = 0; i < 9; i++) {
    candidates[i] = i + 1;
    }
    findEqualN(candidates, result, new ArrayList<>(), 0, n, k);
    return result;
    }
    private static void findEqualN(int[] candidates, List
    > result, List
    path, int start, int target, int k) { if (target < 0) { return; } if (target == 0) { if (path.size() == k) { result.add(new ArrayList<>(path)); } return; } for (int i = start; i < candidates.length; i++) { int num = candidates[i]; if (num > target) { continue; } if (path.contains(num)) { continue; } path.add(num); findEqualN(candidates, result, path, i, target - num, k); path.remove(); } } }

    4. 组合总和 IV

    题目描述

    给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。顺序不同的序列被视作不同的组合。

    示例

    输入:nums = [1, 2, 3], target = 4 输出:7种组合。

    解题思路

    使用动态规划的方法,创建一个dp数组,dp[i]表示组合数为i时使用nums中的数能组成的组合数的个数。通过遍历数组中的每个数,更新dp数组,统计满足条件的组合数。

    代码实现

    public class Solution {
    public int combinationSum4(int[] nums, int target) {
    int[] dp = new int[target + 1];
    dp[0] = 1;
    for (int i = 1; i <= target; i++) {
    for (int num : nums) {
    if (i >= num) {
    dp[i] += dp[i - num];
    }
    }
    }
    return dp[target];
    }
    }

    5. 全排列

    题目描述

    给定一个没有重复数字的序列,返回其所有可能的全排列。

    示例

    输入:[1, 2, 3] 输出:6种排列。

    解题思路

    使用递归的方法,生成所有可能的排列。通过交换元素位置的方式,确保每个排列都是唯一的。

    代码实现

    import java.util.ArrayList;
    import java.util.List;
    public class Solution {
    public List
    > permute(int[] nums) {
    List
    > result = new ArrayList<>();
    return recursion(result, nums, 0, nums.length - 1);
    }
    public static List
    > recursion(List
    > result, int[] nums, int begin, int end) { List
    path = new ArrayList<>(); if (begin == end) { for (int i = 0; i <= end; i++) { path.add(nums[i]); } result.add(new ArrayList<>(path)); return result; } else { for (int j = begin; j <= end; j++) { swap(nums, begin, j); recursion(result, nums, begin + 1, end); swap(nums, begin, j); } } return result; } private static void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } }

    6. 单词搜索

    题目描述

    给定一个二维网格和一个单词,找出该单词是否存在于网格中。单词必须按照字母顺序,通过相邻的单元格内的字母构成,相邻单元格是水平或垂直的。

    示例

    网格:

    ['A', 'B', 'C', 'E']
    ['S', 'F', 'C', 'S']
    ['A', 'D', 'E', 'E']

    单词:"ABCCED",返回true。

    解题思路

    使用深度优先搜索(DFS),记录每个访问过的单元格,避免重复访问。检查单词是否能按顺序找到。

    代码实现

    public class Solution {
    public boolean exist(char[][] board, String word) {
    char[] chs = word.toCharArray();
    int rows = board.length;
    int cols = board[0].length;
    boolean[][] visited = new boolean[rows][cols];
    for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
    if (isvalid(i, j, chs, 0, visited)) {
    return true;
    }
    }
    }
    return false;
    }
    private boolean isvalid(int row, int col, char[] chs, int index, boolean[][] visited) {
    if (row < 0 || row >= visited.length || col < 0 || col >= visited[0].length) {
    return false;
    }
    if (visited[row][col]) {
    return false;
    }
    if (index >= chs.length) {
    return true;
    }
    if (board[row][col] == chs[index]) {
    visited[row][col] = true;
    if (isvalid(row, col, chs, index + 1, visited)) {
    return true;
    }
    visited[row][col] = false;
    }
    return false;
    }
    }

    7. 最大单词长度乘积

    题目描述

    给定一个字符串数组,找到两个单词的长度乘积的最大值,前提是它们没有公共字母。如果没有这样的两个单词,返回0。

    示例

  • 输入:["abcw", "baz", "foo", "bar", "xtfn", "abcdef"] 输出:16
  • 输入:["a", "ab", "abc", "d", "cd", "bcd", "abcd"] 输出:4
  • 输入:["a", "aa", "aaa", "aaaa"] 输出:0
  • 解题思路

    首先统计每个单词的字母频率,然后找出两个没有公共字母的单词,计算它们的长度乘积的最大值。

    代码实现

    public class Solution {
    public int maxProduct(String[] words) {
    int[] letterCount = new int[26];
    for (String word : words) {
    for (char c : word.toCharArray()) {
    letterCount[c - 'a']++;
    }
    }
    int maxProduct = 0;
    for (int i = 0; i < words.length; i++) {
    int[] cnt1 = letterCount;
    for (int j = i + 1; j < words.length; j++) {
    int[] cnt2 = letterCount;
    if (checkOverlap(words[i], cnt1, words[j], cnt2)) {
    int product = words[i].length() * words[j].length();
    if (product > maxProduct) {
    maxProduct = product;
    }
    }
    }
    }
    return maxProduct;
    }
    private boolean checkOverlap(String word1, int[] cnt1, String word2, int[] cnt2) {
    for (char c : word1.toCharArray()) {
    if (cnt2[c - 'a'] > 0) {
    return true;
    }
    }
    return false;
    }
    }

    通过以上内容,可以看到回溯算法在解决各种组合问题中的应用。每个问题都有其独特的挑战,但通过系统的分析和优化,可以找到有效的解决方案。

    转载地址:http://udhq.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现redis分布式锁(附完整源码)
    查看>>
    Objective-C实现regular-expression-matching正则表达式匹配算法(附完整源码)
    查看>>
    Objective-C实现relu线性整流函数算法(附完整源码)
    查看>>
    Objective-C实现restful api服务(附完整源码)
    查看>>
    Objective-C实现reverse letters反向字母算法(附完整源码)
    查看>>
    Objective-C实现ReverseNumber反转数字算法 (附完整源码)
    查看>>
    Objective-C实现ReversePolishNotation逆波兰表示法算法 (附完整源码)
    查看>>
    Objective-C实现RGB Hsv 转换算法(附完整源码)
    查看>>
    Objective-C实现RGB和HSV相互转换算法(附完整源码)
    查看>>
    Objective-C实现RGB转十六进制算法(附完整源码)
    查看>>
    Objective-C实现ripple adder涟波加法器算法(附完整源码)
    查看>>
    Objective-C实现RKM匹配(附完整源码)
    查看>>
    Objective-C实现RodCutting棒材切割最大利润算法(附完整源码)
    查看>>
    Objective-C实现roman numerals罗马数字算法(附完整源码)
    查看>>
    Objective-C实现Romberg算法(附完整源码)
    查看>>
    Objective-C实现ROT13密码算法(附完整源码)
    查看>>
    Objective-C实现rotate matrix旋转矩阵算法(附完整源码)
    查看>>
    Objective-C实现round robin循环赛算法(附完整源码)
    查看>>
    Objective-C实现RRT路径搜索(附完整源码)
    查看>>
    Objective-C实现RS485通信接收数据(附完整源码)
    查看>>