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

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

回溯算法与力扣题解

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/

    你可能感兴趣的文章
    PHP数组排序函数array_multisort()函数详解(二)
    查看>>
    php数组的几个函数和超全局变量
    查看>>
    PHP文件上传详解
    查看>>
    PHP文件锁
    查看>>
    php文本框输入制定文本,php – 当用户没有向文本框输入任何内容时...
    查看>>
    PHP时间戳和日期相互转换操作总结
    查看>>
    php时间戳知识点,php 时间戳函数总结与示例
    查看>>
    php更新数据库失败,php – 无法更新MySQL数据库
    查看>>
    php机器人聊天对话框,基于AIML的PHP聊天机器人
    查看>>
    PHP查找数组中最大值与最小值
    查看>>
    php查最大值,在PHP数组中查找最大值
    查看>>
    php标签筛选,关于PHP CodeIgniter框架中通过<a>标签和url做多条件分类筛选
    查看>>
    php根据年月日计算年龄
    查看>>
    RabbitMQ - 单机部署(超详细)
    查看>>
    php检查注册,PHP检查注册的电子邮件地址是一个’school.edu’地址
    查看>>
    php模拟发送GET和POST请求
    查看>>
    RabbitMQ - 以 MQ 为例,手写一个 RPC 框架 demo
    查看>>
    php模板引擎smarty
    查看>>
    php正则表达式模式
    查看>>
    php正则表达式的特殊字符含义
    查看>>