华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
看不懂有疑问需要答疑辅导欢迎私VX: code5bug
题目描述
给定一个整数数组 nums、一个数字k,一个整数目标值 target,请问nums中是否存在k个元素使得其相加结果为target,请输出所有符合条件且不重复的k元组的个数
数据范围
- 2<= nums.length <= 200
- -109 <= nums[i] <= 109
- -109 <= target <= 109
- 2 <=k<= 100
输入描述
第一行是nums 取值:2 7 11 15
第二行是k的取值:2
第三行是target取值:9
输出描述
输出第一行是符合条件的元祖个数:1
补充说明:
[2,7]满足,输出个数是1
示例1
输入:
-1 0 1 2 -1 -4
3
0
输出:
2
说明:
-1 0 1, -1 -1 2 满足条件
示例2
输入:
2 7 11 15
2
9
输出:
1
说明:
2 7 符合条件
题解
目类型
这道题目属于**回溯算法(Backtracking)**的范畴,类似于组合求和问题。我们需要在给定的数组中找到所有不重复的k元组,使得它们的和等于目标值target。由于需要枚举所有可能的组合并避免重复,回溯算法是一个合适的选择。
解题思路
- 排序:首先对数组进行排序,这样可以方便地跳过重复的元素,避免生成重复的组合。
- 回溯:使用回溯算法来生成所有可能的k元组。在每一步,我们决定是否选择当前元素,并递归处理剩下的元素。
- 剪枝:在递归过程中,如果当前的和已经不可能满足条件(例如,剩余的元素不足以构成k元组),则提前终止递归(剪枝),以提高效率。
- 去重:在排序的基础上,跳过连续相同的元素,确保生成的组合不重复。
Python
"""
@author: code5bug
"""
nums = list(map(int, input().split()))
k = int(input())
target = int(input())
nums.sort() # 排序以便跳过重复元素
ans = 0 # 记录满足条件的组合数
def backtrack(idx: int, total: int, left_k: int):
"""
回溯函数,寻找满足条件的k元组
:param idx: 当前处理的元素索引
:param total: 当前已选元素的和
:param left_k: 剩余需要选择的元素个数
"""
global nums, ans, target
# 找到答案组合
if left_k == 0 and total == target:
ans += 1
return
# 终止条件:索引越界或已无剩余元素需要选择
if idx == len(nums) or left_k == 0:
return
for i in range(idx, len(nums)):
# 跳过重复元素,避免生成重复组合
if i > idx and nums[i] == nums[i - 1]:
continue
# 递归处理下一个元素
backtrack(i + 1, total + nums[i], left_k - 1)
backtrack(0, 0, k) # 从索引0开始,初始和为0,剩余k个元素需要选择
print(ans)
希望这个专栏能让您熟练掌握算法, 🎁🎁🎁 。
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏