***leetcode刷题_(arr,math)_code31(下一个数列)_(arr,str,math,回溯)_code22(产生正确的插入顺序的括号)

code31: Next Permutation

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place and use only constant extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

解答:
发现规律
在这里插入图片描述
下一个的最小数列。
1 比原数列大
2 紧接着的下一个
3 特殊情况 已经是最大值 则直接返回最小值

总的规律就是,逆向推进时,开始变小(a[i-1]<a[i])时,临界点。此时需要找到右边比a[i-1]大的 最小值 并调换。然后右边整块做reverse。
(这个规律确实比较难发现!)

然后代码注意:
1 反向遍历找到临界点
2 临界处 做右边块的遍历。找到第二个临界点。(此时边界情况:遍历到最后 还是大的话 直接交换最后一位。)
3 交换后 reverse右边块
4 最后检查是否进入临界点(用count计数),如果等于零,没进入 代表本身最大值。直接reverse。
5 注意: if else 多了时 外面有while ,要注意 break

code:

class Solution:
    def nextPermutation(self, nums) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        l = len(nums)
        count = 0
        for i in range(1, l):

            if nums[l - i] > nums[l - i - 1]:
                count += 1
                j = 0
                while j <= len(nums[l - i:]):
                    if j == len(nums[l - i:])-1 and nums[l - i + j] > nums[l - i - 1]:
                        #print('##')
                        y = nums[l - i - 1]
                        nums[l - i - 1] = nums[-1]
                        nums[-1] = y
                        break

                    elif nums[l - i + j] > nums[l - i - 1]:
                        #print('###')
                        j += 1
                    else:
                        #print('####')
                        x = nums[l - i - 1]
                        nums[l - i - 1] = nums[l - i + j - 1]
                        nums[l - i + j - 1] = x
                        break

                
                temp = nums[l-i:]
                temp.reverse()
                nums[l-i:]=temp
                #print(nums)

                break
        if count == 0:
            nums.reverse()

code22: Generate Parentheses

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]

解答:
寻找规律,如何产生。
想到stack可以实现,即可以分为两个步骤
1 pop stack(如果为空,则不进行这步,如果不空,则pop,然后给元素new_s添加’)’ )
2 push stack(如果原s字符串为空,则不进行此步,如果不空,则将s减去一个,然后push,给元素new_s添加’(’ )

3 临界点:s和stack全空时,将元素new_s添加到数组。

这种方法称之为回溯(backtracking)

boolean solve(Node n) {
    if n is a leaf node {
        if the leaf is a goal node, return true
        else return false
    } else {
        for each child c of n {
            if solve(c) succeeds, return true
        }
        return false
    }
}

大意是 如果是边界节点,操作结束。如果不是,判断某些条件,如果满足条件则进入下一个递归,如果不满足,终止。
题中
边界点:s和stack全空
条件:1)stack不空(进行pop),2)字符串不空(进行push)。满足则继续递归
终止情况:不满足则没有后续
注意点:
1)因为是判断两个条件,要并行,但是条件一种某些传递参数有改变会影响到条件二,所以需要复原
2)采用global获取数组做append操作,然后return
3)鉴于我们操作的是new_s,并不需要s以及stack真实存在。为了循环简单,可以用count1 count2进行替换。

代码:

class Solution:
    global new_arr
    new_arr = []
    def generateParenthesis(self, n: int):
        global new_arr
        count2 = 0
        count1 = n
        new_s = ''
        self.do_generate(count1,count2,new_s)
        return new_arr


    def do_generate(self,count1,count2,new_s):

        if count1 ==0 and count2 == 0:
            global new_arr
            new_arr.append(new_s)
        else:
            #pop
            if count2 !=0:
                count2-=1
                new_s+=')'
                self.do_generate(count1,count2,new_s)

                count2 +=1
                new_s= new_s[:-1]

            #push
            if count1 !=0:
                count1 -=1
                count2+=1
                new_s+='('
                self.do_generate(count1,count2,new_s)

su =Solution()
res = su.generateParenthesis(1)
print(res)
print(len(res))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值