• LeetCode刷题191203 --回溯算法


      虽然不是每天都刷,但还是不想改标题,(手动狗头

      题目及解法来自于力扣(LeetCode),传送门

    算法(78)

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

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

    示例:

    输入: nums = [1,2,3]
    输出:
    [
    [3],
      [1],
      [2],
      [1,2,3],
      [1,3],
      [2,3],
      [1,2],
      []
    ]

      这道题我自己其实一开始没有什么比较好的想法,希望能用循环来解决,但写着写着发现处理情况有些多/循环嵌套次数过多。来一起看看网友给的解法吧,回溯法:

     1 public class Solution {
     2     //回溯法
     3     private IList<IList<int>> res;
     4     private void find(int[] nums, int begin, IList<int> pre)
     5     {
     6         // 没有显式的递归终止
     7         res.Add(new List<int>(pre));// 注意:这里要 new 一下
     8         for (int i = begin; i < nums.Length; i++)
     9         {
    10             pre.Add(nums[i]);
    11             find(nums, i + 1, pre);
    12             pre.RemoveAt(pre.Count - 1);// 组合问题,状态在递归完成后要重置
    13         }
    14     }
    15     public IList<IList<int>> Subsets(int[] nums)
    16     {
    17         int len = nums.Length;
    18         res = new List<IList<int>>();
    19         if (len == 0)
    20         {
    21             return res;
    22         }
    23         IList<int> pre = new List<int>();
    24         find(nums, 0, pre);
    25         return res;
    26     }
    27 }

      回溯算法的一般是这样一个过程:在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索的方法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

      我们回到上面的方法,重点其实在4~14行这个find方法里。这个方法其实只做了两件事,1.向输出结果的res中添加集合。2.准备下一组数据。我们重点看看怎么准备下一组数据。在for循环中定义了起始的索引,终止条件是遍历整个原集合。注意10~12行,这里其实是把集合中数组的个数分隔开来。嗯,换一种表达方式是,假如我们以[0,1,2]这个集合举例。它的所有子集是:[],[0],[0,1],[0,1,2],[0,2],[1],[1,2],[2]. (注意这里的顺序,上面的代码输入也是按这个顺序的)子集中的空集是在第一层调用find时添加进结果集合中的,子集中个数为1的集合是在第二层调用find时添加进去的。理解了这里,也就方便理解了为什么要有12行  pre.RemoveAt(pre.Count - 1);

      

  • 相关阅读:
    HDU 1018.Big Number-Stirling(斯特林)公式 取N阶乘近似值
    牛客网 Wannafly挑战赛9 C.列一列-sscanf()函数
    牛客网 Wannafly挑战赛9 A.找一找-数据处理
    Codeforces 919 C. Seat Arrangements
    Codeforces Round #374 (Div. 2) D. Maxim and Array 线段树+贪心
    Codeforces Round #283 (Div. 2) A ,B ,C 暴力,暴力,暴力
    Codeforces Round #283 (Div. 2) E. Distributing Parts 贪心+set二分
    Codeforces Round #280 (Div. 2) E. Vanya and Field 数学
    Codeforces Round #280 (Div. 2) D. Vanya and Computer Game 数学
    Codeforces Round #280 (Div. 2) A , B , C
  • 原文地址:https://www.cnblogs.com/dogtwo0214/p/11978020.html
Copyright © 2020-2023  润新知