算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
今天和大家聊的问题叫做 组合,我们先来看题面:
https://leetcode-cn.com/problems/combinations/
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
You may return the answer in any order.
题意
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
解题
递归
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
def dfs(start, cur):
# 如果当前已经拿到了K个数的组合,直接加入答案
# 注意要做深拷贝,否则在之后的回溯过程当中变动也会影响结果
if len(cur) == k:
ret.append(cur[:])
return
# 从start+1的位置开始遍历
for i
in range(start+
1, n):
cur.append(i+
1)
dfs(i, cur)
# 回溯
cur.pop()
ret = []
dfs(
-1, [])
return ret
迭代

class Solution:
def combine(self, n:
int,
k:
int) -> List[List[
int]]:
def comb(window,
m,
ret):
ret.
append(window[:-
1])
# 如果第
m位的滑动框不超过直尺的范围并且
m右侧的滑动框
while window[
m] <
min(n -
k +
m +
1, window[
m+
1] -
1):
# 向右滑动一位
window[
m] +=
1
# 如果
m左侧还有滑动框,递归
if
m >
0:
# 把左侧的滑动框全部移动到最左侧
window[:
m] =
range(
1,
m+
1)
comb(window,
m-
1,
ret)
else:
# 否则记录答案
ret.
append(window[:-
1])
ret = []
window =
list(
range(
1,
k+
1))
# 额外多放一个滑动框作为标兵
window.
append(n+
1)
comb(window,
k-
1,
ret)
return
ret
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
# 构造滑动框
window = list(range(
1, k +
1)) + [n +
1]
ret, j = [],
0
while j <
k:
# 添加答案
ret.append(window[
:k])
j =
0
# 从最左侧的滑动框开始判断
# 如果滑动框与它右侧滑动框挨着,那么就将它移动到最左侧
# 因为它右侧的滑动框一定会向右移动
while j < k
and window[j +
1] == window[j] +
1:
window[j] = j +
1
j +=
1
# 连续挨着最右侧的滑动框向右移动一格
window[j] +=
1
return ret
总结
上期推文:
本文分享自微信公众号 - 程序IT圈(DeveloperIT)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/2898531/blog/4689984