• LeetCode高频题78. 子集,返回该数组所有可能的子集(幂集),生成所有的子序列


    LeetCode高频题78. 子集,返回该数组所有可能的子集(幂集),生成所有的子序列

    提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目
    互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!
    你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题
    在这里插入图片描述
    基础知识:
    【1】LeetCode高频题46. 全排列


    题目

    给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

    解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。


    一、审题

    示例 1:

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

    输入:nums = [0]
    输出:[[],[0]]

    提示:

    1 <= nums.length <= 10
    -10 <= nums[i] <= 10
    nums 中的所有元素 互不相同

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/subsets
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


    这不就是暴力枚举每个位置要还是不要整出来的所有情况吗?

    在这里插入图片描述
    就是暴力递归就行了
    定义一个函数:

    f(int[] arr, int i, LinkedList<Integer> tmp, List<List<Integer>> ans)
    
    • 1

    啥含义呢?

    来到arr的i位置,咱们决定i那个数字要?还是不要?
    要的话加入tmp暂存,然后考虑i+1位置
    当i到arr的末尾N位置,一个路径已经决定好了,把tmp放入结果ans中

    然后清除现场,tmp把刚刚加入的i位置那个数字扔掉,继续考虑别的情况

    啥叫清楚现场呢?
    就是下面左边的3,tmp=123,算一种情况,你要考虑3不要的情况
    进f之前,自然要把3吐出去,这样tmp才能走右边的路,因为我们一直重复用一个tmp,所以自然一种情况考虑完,要吐掉,然后考虑别的情况
    在这里插入图片描述
    这已经是非常简单的暴力递归了
    之前咱们讲全排列时,已经说过了,这个比全排列简单

    【1】LeetCode高频题46. 全排列

    okay,咱们手撕本题代码,超级简单的

            public List<List<Integer>> subsets(int[] nums) {
                List<List<Integer>> ans = new ArrayList<>();
    
                LinkedList<Integer> tmp = new LinkedList<>();//中途放tmp
    
                f(nums, 0, tmp, ans);//从i=0--N收集答案
    
                return ans;
            }
    
            // 这不就是暴力枚举每个位置要还是不要整出来的所有情况吗?
            //从左往右来到i位置,决定要还是不要?
    
            //来到arr的i位置,中途决定好的放tmp
            //当i=N位置就把东西放ans中收集好
            public static void f(int[] arr, int i, LinkedList<Integer> tmp, List<List<Integer>> ans){
                if (i == arr.length){
                    ans.add(new ArrayList<>(tmp));//中途可能需要恢复现场的
                    return;
                }
                //2种,要还是不要
                f(arr, i + 1, tmp, ans);//不要
                tmp.addLast(arr[i]);
                f(arr, i + 1, tmp, ans);//要
                tmp.removeLast();//恢复现场,考虑别的情况
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    测试:

        public static void test(){
            int[] arr = {1,2,3};
    
            Solution solution = new Solution();
            List<List<Integer>> ans = solution.subsets(arr);
            for(List<Integer> lists : ans){
                for(Integer i:lists) System.out.print(i +" ");
                System.out.println();
            }
        }
    
        public static void main(String[] args) {
            test();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    --3 
    2 
    2 3 
    1 
    1 3 
    1 2 
    1 2 3 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    LeetCode测试:
    在这里插入图片描述
    在这里插入图片描述
    本题暴力归队就是最好的方案

    因为每一个情况都要遍历,所以没有优化的空间

    done!


    总结

    提示:重要经验:

    1)全排列和这种组合问题,老掉牙的暴力递归,恢复现场,多次说过了
    3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

  • 相关阅读:
    WebPack5基础使用总结(一)
    58-Console接口电路设计
    贪心算法-均分纸牌-JAVA
    Linux软件管理
    C语言描述数据结构 —— 栈和队列OJ题
    尚品汇 - 项目个人笔记总汇(更新中...)
    停车场如何通过金万维快解析实现数据共享
    web 性能优化详解(Lighthouse工具、优化方式、强缓存和协商缓存、代码优化、算法优化)
    数据安全中的存储安全包含哪些内容,如何实现数据存储安全
    分布式锁的实现(二)zookeeper篇
  • 原文地址:https://blog.csdn.net/weixin_46838716/article/details/126191237