首页 > 其他分享 >day29| 491+46+47

day29| 491+46+47

时间:2023-04-13 23:23:13浏览次数:52  
标签:tmp day29 nums 46 47 List res check first

491. 递增子序列

 

题目简述:

给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

 

思路:

 

关键在去重

利用官方题解给的思路:判断当前遍历到的数字与上一次被选的数字是否相等

1. 若相等,则不能不选当前数字

2. 若不等,方可考虑不选当前数字

 

代码如下:

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:

        def dfs(i, tmp):
            if i == len(nums):
                if len(tmp) >= 2:
                    res.append(tmp[:])      # 拷贝,tmp[:]而非tmp
                return
            
            # 选 nums[i]
            if not tmp or nums[i]>=tmp[-1]: # 需满足递增
                tmp.append(nums[i])         # 选nums[i]
                dfs(i+1, tmp)
                tmp.pop()                   # 回溯复原
                # dfs(i+1, tmp+[nums[i]])   # 与以上三行等价
            
            # 不选 nums[i]:
            # 只有在nums[i]不等于前一项tmp[-1]的情况下才考虑不选nums[i]
            # 即若nums[i] == tmp[-1],则必考虑选nums[i],不予执行不选nums[i]的情况
            if not tmp or (tmp and nums[i] != tmp[-1]): # 避免重复
                dfs(i+1, tmp)


        res = []
        dfs(0, [])
        return res

 

 

46. 全排列

 

题目简述:

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

 

思路:

 

不断交换,输出nums

 

代码如下:

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:

    

        def backtrack(first = 0):
            # 所有数都填完了
            if first == n:  
                res.append(nums[:])
            for i in range(first, n):
                # 动态维护数组
                nums[first], nums[i] = nums[i], nums[first]
                # 继续递归填下一个数
                backtrack(first + 1)
                # 撤销操作
                nums[first], nums[i] = nums[i], nums[first]
        
        n = len(nums)
        res = []
        backtrack()
        return res

 

 

47. 全排列II

 

题目简述:

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

 

思路:

1. 多加一个used数组记录元素使用情况

2. 利用used数组,在回溯过程中执行剪枝操作

 

代码如下:

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        def backtrace(first,path,nums,check):
            if first==n:
                res.append(path[:])
                return
            
            for i in range(n):
                if check[i]==1:
                    continue
                if i>0 and nums[i-1]==nums[i] and check[i-1]==0:
                    continue
                
                check[i]=1
                backtrace(first+1,path+[nums[i]],nums,check)
                check[i]=0
                
        n=len(nums)
        nums.sort()
        check=[0 for _ in range(n)]
        res=[]
        backtrace(0,[],nums,check)
        return res

 

 

总结:

1. 如何巧妙设计取值的方式和回溯的方式是一个大难点

2. 如何剪枝也是一个难点

标签:tmp,day29,nums,46,47,List,res,check,first
From: https://www.cnblogs.com/cp1999/p/17316505.html

相关文章

  • HDU 4628 Pieces (状压DP)
    题目地址:HDU4628这题没想到怎么快速枚举子状态。。。看了题解才知道的。用for(state=i;state>0;state=(state-1)&i)就可以了。这题的具体做法是先预处理出所有的状态是不是回文串,然后就是普通的DP了。代码如下:#include<iostream>#include<string.h>#include<math.h>......
  • Educational Codeforces Round 146 (Rated for Div. 2)
    Preface补题ing值得一提的时补这场的时候先是遇上了CF的12小时大维护,后面又遇到了评测机崩了测不了也是有点有意思的说A.Coins傻逼题,首先考虑\(2|n\)时一定有解\(x=\frac{n}{2},y=0\),否则若\(2\nmidn\and2|k\)则由裴蜀定理知此时一定无解否则\(y\)必为奇数,我们令\(x=\fra......
  • CF1473D 题解
    题目传送门题目分析线段树、前缀和、\(\text{ST}\)表题解都有了,我补一发猫树题解吧。由于每次操作只能将大小改变成跟原来差\(1\),所以只需要知道这段操作中的最大值和最小值,最后所求的答案的范围就被卡住了。对于每一次操作,我们把操作序列拦腰斩断,那么分别求两边的范围,最后减......
  • HDU 2473 Junk-Mail Filter(并查集的删除操作)
    题目地址:HDU2473这题以前碰到过,没做出来。。现在又做了做,还是没做出来。。、、这题涉及到并查集的删除操作。想到了设一个虚节点,但是我把虚节点设为了要删除的点的父节点,一直是栈溢出,目测是无限递归了。看了看别人的做法,原来只要建一个映射就可以了,虚节点是作为的新的映射,每......
  • Calling Circles UVA - 247
    如果两个人相互打电话(直接或间接),则说他们在同一个电话圈里。例如,a打给b,b打给c,c打给d,d打给a,则这4个人在同一个圈里;如果e打给f但f不打给e,则不能推出e和f在同一个电话圈里。输入n(n≤25)个人的m次电话,找出所有电话圈。人名只包含字母,不超过25个字符,且不重复 对于一个有向图,Flo......
  • abc247_f Cards 题解
    Cards题意有\(N\)张卡片,每张卡片上都写有两个数字,第\(i\)张卡片上的数字分别为\(P_i,Q_i\)。同时,\(P=(P_1,P_2,\dots,P_N)\)和\(Q=(Q_1,Q_2,\dots,Q_N)\)都是\((1,2,\dots,N)\)的全排列。我们需要在\(N\)张卡片中选出一些卡片,并且\(1,2,\dots,N......
  • [C++]LeetCode1147. 段式回文
    [C++]LeetCode1147.段式回文题目描述Difficulty:困难RelatedTopics:贪心,双指针,字符串,动态规划,哈希函数,滚动哈希你会得到一个字符串text。你应该把它分成k个子字符串(subtext1,subtext2,…,subtextk),要求满足:subtexti是非空字符串所有子字符串的连接......
  • UVa 846 Steps (数学)
    846-StepsTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=99&page=show_problem&problem=787Onestepsthroughintegerpointsofthestraightline.Thelengthofastepmustbenonnegat......
  • UVa 443 / POJ 2247 Humble Numbers (4因子-丑数&STL灵活运用)
    443-HumbleNumbersTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=384http://poj.org/problem?id=2247Anumberwhoseonlyprimefactorsare2,3,5or7isc......
  • S460N化学成分、S460N交货状态、S460N性能介绍
    一、S460N钢板简介:S460N:是欧标低合金高强度钢板,执行EN10025标准。S460N钢板生产厚度在8mm-400mm之间,具有高强度及韧性。S460N钢板牌号表示:“S”:表示欧标高钢板;“460”:表示该钢板屈服强度不小于460MPa;“N”:表示钢板交货状态。二、S460N钢板化学成分:CSiMnPSNiCrMoCuNbVTiAltN≤0.2≤......