给定数组,试求能否从数组中取出n个不复用的数的和为sum

本文回顾了一次面试中遇到的问题,即如何从包含小数和正负数的数组中找出n个不重复的数,使得它们的和等于给定的sum。通过深度搜索解决这个问题,关键在于正确设定边界条件。当sum=0且n=0时成功,n<=0则路径结束,n>0则继续搜索。由于数组中既有正数也有负数,因此sum只能在最后用于满足和的判断。文章强调理解和熟练掌握各种边界情况的重要性。
摘要由CSDN通过智能技术生成

这是之前在一次面试中遇到的一道题,当时因为太久没撸算法,太久没刷题,所以gg,现在回顾一下。

问题描述
实现一个函数,传3个参数,指定数组(有小数、正负数),n(取出个数),sum(指定和),输出是否能找到这几个数。

这和经典的凑硬币问题其实本质上是相同的,自然可以用动态规划来做,但这里我们先考虑用深度搜索来做做。

关键就是这些边界的选择设置,我在这里也调了很久,这还是得多练,熟能生巧

边界条件

  • sum=0&n=0,成功get;
  • n<=0,这条路径跪了;
  • n>0,继续搜索->>>

因为数组中有正有负,所以sum只能用于最后的满足判断

处理关键是各种情况都需要有确定的逐层return,因此只要你的考虑周全,边界判断可以灵活改变。

完整代码如下:成功返回true,失败返回false

function findGroup(arr,n,sum){
   
    
可以使用回溯算法来解决这个问题。具体步骤如下: 1. 定义一个方法 backtrack(int[] nums, int target, int start, List<Integer> path, List<List<Integer>> res),其中 nums 表示输入的正整数组,target 表示目标和,start 表示从哪个位置开始搜索,path 表示当前的路径,res 表示最终的结果集。 2. 在 backtrack 方法中,首先判断当前的路径是否满足条件,如果满足,则将其加入结果集中。 3. 然后从 start 开始遍历数组,对于每个数,将其加入当前路径中,更新目标和,然后递归调用 backtrack 方法。 4. 在递归调用完成后,需要将当前从路径中删除,同时将目标和恢复到之前的状态。 下面是 Java 代码实现: ``` public List<List<Integer>> findNsum(int[] nums, int target, int start, int N) { List<List<Integer>> res = new ArrayList<>(); int len = nums.length; if (N < 2 || len < N) return res; if (N == 2) { int left = start, right = len - 1; while (left < right) { int sum = nums[left] + nums[right]; if (sum == target) { List<Integer> path = new ArrayList<>(); path.add(nums[left]); path.add(nums[right]); res.add(path); while (left < right && nums[left] == nums[left + 1]) left++; while (left < right && nums[right] == nums[right - 1]) right--; left++; right--; } else if (sum < target) { left++; } else { right--; } } } else { for (int i = start; i < len - N + 1; i++) { if (i > start && nums[i] == nums[i - 1]) continue; List<List<Integer>> sub = findNsum(nums, target - nums[i], i + 1, N - 1); for (List<Integer> path : sub) { path.add(0, nums[i]); res.add(path); } } } return res; } ``` 其中,findNsum 方法中的参分别表示:nums 表示输入的正整数组,target 表示目标和,start 表示从哪个位置开始搜索,N 表示要找的个数。在方法中,首先判断 N 的值,如果是 2,就使用双指针法查找满足条件的两个数;否则,就递归调用 findNsum 方法,在子问题中查找 N-1 个数的和为 target-nums[i] 的路径,并将 nums[i] 加入路径中,最后将路径加入结果集中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值