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

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

这篇文章是关于我今天所做的关于回溯算法的题(出自力扣),参考了力扣上几位大牛的算法,在此表示感谢!

  1. 组合总和
  2. 组合总和 II
  3. 组合总和 III
  4. 组合总和 IV
  5. 全排列
  6. 单词搜索
  7. 最大单词长度乘积

1. 组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[ [7], [2,2,3]]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[ [2,2,2,2], [2,3,3], [3,5]]

class Solution {    public List
> combinationSum(int[] candidates, int target) { List
> list =new ArrayList<>(); Arrays.sort(candidates); findAllCombine(list,candidates,target,0,new ArrayList
()); //System.out.println(list); return list; } private static void findAllCombine(List
> list, int[] candidates, int target, int start, ArrayList
al) { //System.out.println("target:"+target); if(target<0) { return; } if(target==0) { list.add(new ArrayList
(al)); return; } for(int i=start;i

2. 组合总和 II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,

所求解集为:
[ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6]]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]

class Solution {    public List
> combinationSum2(int[] candidates, int target) { List
> list=new ArrayList<>(); Arrays.sort(candidates); findAllOnly(list,new ArrayList
(),candidates,target,0); //System.out.println(list); return list; } private static void findAllOnly(List
> list, ArrayList
al, int[] candidates, int target, int start) { if(target<0) { return ; } if(target==0) { if(!list.contains(al)) { list.add(new ArrayList<>(al)); } return; } for(int i=start;i

3. 组合总和 III

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
所有数字都是正整数。
解集不能包含重复的组合。
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:

输入: k = 3, n = 9

输出: [[1,2,6], [1,3,5], [2,3,4]]

class Solution {    public List
> combinationSum3(int k, int n) { List
> ls=new ArrayList<>(); int [] candidates=new int[9]; for(int i=0;i<9;i++) { candidates[i]=i+1; } //System.out.println(Arrays.toString(candidates)); //找到九个数中等于n的排列组合 findEqualN(candidates,ls,new ArrayList
(),0,n,k); //System.out.println(ls); return ls; } private static void findEqualN(int[] candidates, List
> ls, ArrayList
al, int start, int target, int k) { if(target<0) { return; } if(target==0) { if(al.size()==k) { ls.add(new ArrayList<>(al)); } return ; } for(int i=start;i

4. 组合总和 IV

给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

示例:

nums = [1, 2, 3]

target = 4

所有可能的组合为:

(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

请注意,顺序不同的序列被视作不同的组合。

因此输出为 7。

进阶:
如果给定的数组中含有负数会怎么样?
问题会产生什么变化?
我们需要在题目中添加什么限制来允许负数的出现?
注:这是力扣上那位大牛的代码,我没有改

class Solution {    public int combinationSum4(int[] nums, int target) {        //dfs会超时        //使用dp数组,dp[i]代表组合数为i时使用nums中的数能组成的组合数的个数        //别怪我写的这么完整        //dp[i]=dp[i-nums[0]]+dp[i-nums[1]]+dp[i=nums[2]]+...        //举个例子比如nums=[1,3,4],target=7;        //dp[7]=dp[6]+dp[4]+dp[3]        //其实就是说7的组合数可以由三部分组成,1和dp[6],3和dp[4],4和dp[3];        int[]dp=new int[target+1];        //是为了算上自己的情况,比如dp[1]可以由dp【0】和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]

输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

class Solution {    public List
> permute(int[] nums) { List
>arraylist=new ArrayList<>(); return recursion(arraylist, nums, 0, nums.length-1); } //核心 public static List
> recursion(List
> al,int[]nums,int begin,int end){ List
al2=new ArrayList<>(); if(begin==end){ for(int i=0;i<=end;i++){ al2.add(nums[i]); } al.add(al2); return al; }else{ for(int j=begin;j<=end;j++){ exch(nums,begin,j); recursion(al,nums, begin+1, end); exch(nums,begin,j); } return al; } } //交换 private static void exch(int[] nums, int i, int j) { int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; }}

6. 单词搜索

给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board =
[ [‘A’,‘B’,‘C’,‘E’],[‘S’,‘F’,‘C’,‘S’], [‘A’,‘D’,‘E’,‘E’]]
给定 word = “ABCCED”, 返回 true.
给定 word = “SEE”, 返回 true.
给定 word = “ABCB”, 返回 false.

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
=0 && row
=0 && col

7. 最大单词长度乘积

给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。

示例 1:

输入: [“abcw”,“baz”,“foo”,“bar”,“xtfn”,“abcdef”]

输出: 16
解释: 这两个单词为 “abcw”, “xtfn”。
示例 2:

输入: [“a”,“ab”,“abc”,“d”,“cd”,“bcd”,“abcd”]

输出: 4
解释: 这两个单词为 “ab”, “cd”。
示例 3:

输入: [“a”,“aa”,“aaa”,“aaaa”]

输出: 0
解释: 不存在这样的两个单词。

class Solution {    public int maxProduct(String[] words) {        //先将所有的单词用32的整数进行表示		int [] val=new int[words.length];		for(int i=0;i

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

你可能感兴趣的文章
MYSQL语句。
查看>>
MySQL调优是程序员拿高薪的必备技能?
查看>>
MySQL调大sort_buffer_size,并发量一大,查询排序为啥又会变慢
查看>>
Mysql账号权限查询(grants)
查看>>
mysql转达梦7_达梦7的子查询分解示例说明
查看>>
MYSQL输入密码后闪退的解决方法
查看>>
MySQL迁移到达梦:如何轻松、高质量完成迁移任务
查看>>
mysql返回的时间和实际数据存储的时间有误差(java+mysql)
查看>>
mysql还有哪些自带的函数呢?别到处找了,看这个就够了。
查看>>
Mysql进入数据库
查看>>
mysql进阶 with-as 性能调优
查看>>
mysql进阶-查询优化-慢查询日志
查看>>
wargame narnia writeup
查看>>
MySQL进阶篇SQL优化(InnoDB锁问题排查与解决)
查看>>
Mysql进阶索引篇03——2个新特性,11+7条设计原则教你创建索引
查看>>
mysql远程连接设置
查看>>
MySql连接出现1251Client does not support authentication protocol requested by server解决方法
查看>>
Mysql连接时报时区错误
查看>>
MySql连接时提示:unknown Mysql server host
查看>>
MySQL连环炮,你扛得住嘛?
查看>>