前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Leetcode分类——递归、回溯、分治

Leetcode分类——递归、回溯、分治

作者头像
matt
发布2022-10-25 16:04:47
2660
发布2022-10-25 16:04:47
举报
文章被收录于专栏:CSDN迁移

Leetcode分类——递归、回溯、分治

递归与回溯的区别

回溯是一种应用递归算法,递归不是

Leetcode 78

题目 循环的困难之处在于不好模拟选不选某一个数的过程,即选了一个数,不方便回溯到不选这个数的情况。

代码语言:javascript
复制
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。

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

解法一:回溯法

代码语言:javascript
复制
class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> list = new ArrayList();//存放结果
        List<Integer> temp = new ArrayList<>();//存放一次完整递归的结果
        //递归放入
        addElem(nums, 0, temp, list);
        return list;
    }

    private void addElem(int[] nums, int n, List<Integer> temp, List<List<Integer>> list) {
        //递归的出口
        if (n >= nums.length) {
            List addTemp = new ArrayList(temp);
            list.add(addTemp);
            //list.add(temp);//关键:如果直接放入temp,则所有结果都等于最后一次放入的情况
            return;
        }

		//放入该元素
        temp.add(nums[n]);
        addElem(nums, n + 1, temp, list);
		//回溯,不放入该元素
        temp.remove(temp.size() - 1);
        addElem(nums, n + 1, temp, list);
    }
}

方法二:位运算 位运算介绍:

  • & 按位与
  • | 按位或
  • ^ 按位异或:相同为0,不同为1
  • ~ 取反
  • << 左移:乘以2
  • >> 右移:除以2

这里的集合有三个元素A、B、C,则三个元素共有2^3=8种组成集合的方式,于是可以用0(000)~7(111)来表示这些集合。

集合

整数

A

B

C

{}

000=0

0

0

0

{C}

001=1

0

0

1

{B}

010=2

0

1

0

{B,C}

011=3

0

1

1

{A}

100=4

1

0

0

{A,C}

101=5

1

0

1

{A,B}

110=6

1

1

0

{A,B,C}

111=7

1

1

1

A元素为100=4,B元素为010=2,C元素为001=1。如需判断一个集合是否含有该元素,将这个集合的二进制表示与该元素的二进制表示做**&运算**,结果为真时,表示包含该元素,将其push进集合内。

代码语言:javascript
复制
9-1000000000
8-0100000000
7-0010000000
6-0001000000
5-0000100000
4-0000010000
3-0000001000
2-0000000100
1-0000000010
0-0000000001

9 8 7 6 5 4 3 2 1
组合共有2^10 = 1024种

Leetcode 90

题目 利用set将list中相同的list剔除。

代码语言:javascript
复制
class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> list = new ArrayList();
        List<Integer> temp = new ArrayList<>();
        //需要对输入事先排序,使得得到的重复list顺序相同,能够被set认为是重复项
        Arrays.sort(nums);
        addElem(nums, 0, temp, list);
        //将list<list>存为set<list>类型去重,最后转换为list
        return new ArrayList<>(new HashSet<>(list));
    }

    private void addElem(int[] nums, int n, List<Integer> temp, List<List<Integer>> list) {
        if (n >= nums.length) {
            List addTemp = new ArrayList(temp);
            list.add(addTemp);
            return;
        }

        temp.add(nums[n]);
        addElem(nums, n + 1, temp, list);

        temp.remove(temp.size() - 1);
        addElem(nums, n + 1, temp, list);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Leetcode分类——递归、回溯、分治
  • 递归与回溯的区别
  • Leetcode 78
  • Leetcode 90
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档