You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/** * 1. 可以使用指针等方法实现 之前在看代码随想录的时候已经实现过 * let arr = [1,4,7,11,9,8,10,6] * let N = 3; * let M = 27 */functionfindSum(arr,count,sum){constgetCount=function(n){letcount=0;while(n){n&=(n-1)count++}returncount}letlen=arr.length,bit=1<<lenconsole.log('bit: ',parseInt(bit).toString(2));//bit: 1 0000 0000letres=[]for(leti=1;i<bit;i++){if(getCount(i)===count){lets=0,temp=[]for(letj=0;j<len;j++){//判断下标i是否在对应的二进制位置上if(i&1<<(len-1-j)){s+=arr[j]temp.push(arr[j])}}if(s===sum){res.push(temp)}}}returnres}letarr=[1,4,7,11,9,8,10,6]letN=2;letM=5console.log(findSum(arr,N,M))letnum=1<<7console.log(parseInt(num).toString(2))//10000000
Activity
JerryWen1994 commentedon Nov 16, 2020
sisterAn commentedon Nov 16, 2020
解题思路:利用二进制
根据数组长度构建二进制数据,再选择其中满足条件的数据。
我们用
1和0来表示数组中某位元素是否被选中。因此,可以用0110来表示数组中第1位和第2位被选中了。所以,本题可以解读为:
N。M。我们的算法思路逐渐清晰起来: 遍历所有二进制,判断选中个数是否为
N,然后再求对应的元素之和,看其是否为M。1. 从数组中取出 N 个数
例如:
如何判断
N=3是,对应的选取二进制中有几个1喃?最简单的方式就是:
这里我们尝试使用一下位运算来解决本题,因为位运算是不需要编译的(位运算直接用二进制进行表示,省去了中间过程的各种复杂转换,提高了速度),肯定速度最快。
我们知道
1&0=0、1&1=1,1111&1110=1110,即15&14=14,所以我们每次&比自身小1的数都会消除一个1,所以这里建立一个迭代,通过统计消除的次数,就能确定最终有几个 1 了:2. 和为 M
现在最后一层判断就是选取的这些数字和必须等于
M,即根据N生成的对应二进制所在元素上的和 是否为M比如
1110,我们应该判断arr[0] + arr[1] + arr[2]是否为M。那么问题也就转化成了如何判断数组下标是否在
1110中呢?如何在则求和其实也很简单,比如下标
1在,而下标3不在。我们把1转化成0100,1110 & 0100为0100, 大于0,因此下标1在。而1110 & 0001为0,因此 下标3不在。所以求和我们可以如下实现:
最终实现
maimang511 commentedon Dec 20, 2020
回溯的时间复杂度一般是O(n*n!)
webLiang commentedon Sep 26, 2021
https://leetcode-cn.com/circle/article/a8L9ER/ 参考下这个 n 数
xllpiupiu commentedon Oct 5, 2021
NoBey commentedon Mar 23, 2022
black-posterus commentedon Apr 26, 2024