LeetCode 90子集Ⅱ&91解码方法

简介: 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

子集Ⅱ



给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。


示例:


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


分析:


这道题和上道求子集不同的是这里面可能会出现重复的元素。我们需要在结果中过滤掉重复的元素。


首先,子集问题无疑是使用回溯法求得结果,首先分析如果序列没有重复的情况,我们会借助一个boolean[]数组标记使用过的元素和index表示当前的下标,在进行回溯的时候我们只向后进行递归并且将枚举到的那个元素boolean[index]置为true(回来的时候复原)。每次递归收集boolean[]数组中true的元素为其中一个子集。


20201226185326620.png


而有重复元素的处理上,和前面全排列的处理很相似,首先进行排序,然后在进行递归处理的时候遇到相同元素只允许从第一位连续使用而不允许跳着使用,具体可以参考这张图:


20201226185420985.png


实现代码为:


class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
     Arrays.sort(nums);
     boolean jud[]=new boolean[nums.length];
     List<List<Integer>> valueList=new ArrayList<List<Integer>>();
     dfs(nums,-1,valueList,jud);
    return valueList;
      }
  private void dfs(int[] nums, int index, List<List<Integer>> valueList, boolean[] jud)   {
    // TODO Auto-generated method stub
    List<Integer>list=new ArrayList<Integer>();
    for(int i=0;i<nums.length;i++)
    {
      if (jud[i]) {
         list.add(nums[i]);
      }
    }
    valueList.add(list);
    for(int i=index+1;i<nums.length;i++)
    {
      if((i==0)||(nums[i]!=nums[i-1])||(i>0&&jud[i-1]&&nums[i]==nums[i-1]))
      {
        jud[i]=true;
        dfs(nums, i, valueList,jud);
        jud[i]=false;
      }
    }
  }
}


解码方法



一条包含字母 A-Z 的消息通过以下方式进行了编码:


'A' -> 1
'B' -> 2
...
'Z' -> 26


给定一个只包含数字的非空字符串,请计算解码方法的总数。

题目数据保证答案肯定是一个 32 位的整数。


示例 1:

输入:s = "12"
输出:2
解释:它可以解码为 "AB"(1 2)或者 "L"(12)。


示例 2:

输入:s = "226"
输出:3
解释:它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。


示例 3:

输入:s = "0"
输出:0
示例 4:
输入:s = "1"
输出:1


示例 5:

输入:s = "2"
输出:1


提示:

1 <= s.length <= 100
s 只包含数字,并且可能包含前导零。


分析


本题是个动态规划的题,转移方程不是很难但是需要考虑的点比较多。[a-z]之间的字符串。dp[]表示状态转移数组,有以下状态需要考虑:


(1) xx10 xx20 结尾 只能 xx (J) 和 xx(T)这种转换 dp[i]=dp[i-2]

(2) xx40 等数字大于20且%10==0的数字 不可能组合 返回 0

(3) xx01-xx09 分解为x(x0)1-x(x0)9 dp[i]=dp[i-1]

(4) xx27 等大于26分解为xx(2)(7) 那么dp[i]=dp[i-1]

(5) xx25等其他数字可能分解为xx(2)(5)或者xx(25)


实现代码为:


class Solution {
    public int numDecodings(String s) {
       if(s.length()==0||s.charAt(0)=='0')
            return  0;
        char chS[]=s.toCharArray();
        int dp[]=new int[chS.length+1];
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<chS.length+1;i++)
        {
            int value=(chS[i-2]-'0')*10+(int)(chS[i-1]-'0');
            if(value==10||value==20)
                dp[i]=dp[i-2];
            else if(value%10==0)
                return  0;
            else if(value>26||value<10)
                dp[i]=dp[i-1];
            else
                dp[i]=dp[i-1]+dp[i-2];
        }
        return  dp[chS.length];
    }
}



原创不易,bigsai请你帮两件事帮忙一下:


star支持一下, 您的肯定是我在平台创作的源源动力。


微信搜索「bigsai」,关注我的公众号,不仅免费送你电子书,我还会第一时间在公众号分享知识技术。加我还可拉你进力扣打卡群一起打卡LeetCode。


记得关注、咱们下次再见!


目录
相关文章
|
5月前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
212 1
LeetCode第90题子集II
LeetCode第90题"子集II"的解题方法,通过排序和回溯算法生成所有不重复的子集,并使用一个boolean数组来避免同一层中的重复元素,展示了解决这类问题的编码技巧。
LeetCode第90题子集II
|
8月前
|
算法 Go
🚀 力扣热题 78:子集(详细解析)
✅ 回溯法:经典通用模板,逻辑清晰易扩展。 ✅ 二进制法:简洁高效,适合面试快速写出解法。
265 30
|
7月前
|
Go 索引
【LeetCode 热题100】394:字符串解码(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 394:字符串解码。题目要求对编码字符串如 `k[encoded_string]` 进行解码,其中 `encoded_string` 需重复 `k` 次。文章提供了两种解法:使用栈模拟和递归 DFS,并附有 Go 语言实现代码。栈解法通过数字栈与字符串栈记录状态,适合迭代;递归解法则利用函数调用处理嵌套结构,代码更简洁。两者时间复杂度均为 O(n),但递归需注意栈深度问题。文章还总结了解题注意事项及适用场景,帮助读者更好地掌握字符串嵌套解析技巧。
187 6
|
8月前
|
存储 机器学习/深度学习 缓存
🚀 力扣热题 394:字符串解码(详细解析)(Go语言版)
文章提供了两种解法:栈结构和递归解法。栈解法通过维护数字栈与字符串栈,依次处理 `[` 和 `]`,构造解码结果;递归解法则利用函数调用逐层解析嵌套结构。两者时间复杂度均为 $O(n)$,空间复杂度也为 $O(n)$。栈解法直观易懂,适合初学者;递归解法优雅简洁,适合处理深度嵌套规则。掌握这两种方法,可灵活应对类似问题,提升解题能力。
266 11
|
Python
【Leetcode刷题Python】416. 分割等和子集
LeetCode 416题 "分割等和子集" 的Python解决方案,使用动态规划算法判断是否可以将数组分割成两个元素和相等的子集。
180 1
|
算法 Python
【Leetcode刷题Python】百分号解码
深信服公司的算法笔试题.
177 1
|
索引 Python
【Leetcode刷题Python】78. 子集
LeetCode题目78的Python编程解决方案,题目要求给定一个互不相同的整数数组,返回该数组所有可能的子集(幂集),且解集中不能包含重复的子集。
122 1
LeetCode第78题子集
文章分享了LeetCode第78题"子集"的解法,使用递归和回溯算法遍历所有可能的子集,展示了将子集问题视为树形结构进行遍历的解题技巧。
|
算法 Python
LeetCode 常用方法
LeetCode 常用方法

热门文章

最新文章