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))