给定一个包含
n
个整数的数组nums
和一个目标值target
,判断nums
中是否存在x
个元素,使得x1 + x2 + ...
的值与target
相等?找出全部知足条件且不重复的元组。数组
咱们先将这个问题简化,变成下面这个亚子优化
nums
找到知足要求的值,而后push进数组,注意去重let result = []
let hash = {} //使用hash来对结果进行去重
for(let i = 0, len = nums.length; i < len; i++){
if(nums[i] === target && hash[nums[i]] === undefined) {
result.push(nums[i])
hash[nums[i]] = true
}
}
return result
复制代码
nums
找到知足要求的值的组合,而后push进数组,注意去重let result = []
let hash = {} //使用hash来对结果进行去重
️for(let i = 0, len = nums.length; i < len; i++){
for(let j = 0; j < len; j++){
if(nums[i] + nums[j] === target
&& hash[[nums[i], nums[j]]] === undefined
&& hash[[nums[j], nums[i]]] === undefined){
hash[[nums[i], nums[j]]] = true
result.push([nums[i], nums[j]])
}
}
}
return result
复制代码
还可使用键值对象来减小一次循环let map = {}
for(let i = 0, len = nums.length; i < len; i++){
if(map[target - nums[i]] !== undefined){
result.push([nums[i], nums[map[target - nums[i]]]])
} else{
map[nums[i]] = i
}
}
return result
复制代码
for(){
for(){
for(){
···
}
}
}
return result
复制代码
这样看能够解决问题,可是好像不太聪明的亚子。并且若是求全部知足要求的组合,不限制组合中数字的个数就不能用这种层层for循环的解法。spa
排序+指针指针
这种方法适用于2、3、四层循环的优化,具体思路为:先选取一个数组中的数字,而后初始化指针来对其余数字进行遍历,找到知足的条件。code
var threeSum = function(nums, target) {
let result = [],
len = nums.length
if(len < 3){
return result // 边界处理
}
nums.sort((a, b) => a - b) // 排序
// 把L和R都设置在i的后边而且遇到值相等的就把下标日后移动
// 能够保证每次找到的知足要求的组合都是惟一的
for(let i = 0; i < len ; i++){
if(nums[i] === nums[i-1]) continue // 去重
let L = i + 1
let R = len - 1
while(L < R){
let sum = nums[i] + nums[L] + nums[R]
if(sum === 0){
result.push([nums[i],nums[L],nums[R]])
while (L<R && nums[L] === nums[L+1]) L++ // 去重
while (L<R && nums[R] === nums[R-1]) R-- // 去重
L++
R--
}
else if (sum < 0) L++
else if (sum > 0) R--
}
}
return result
}
复制代码
回溯对象
若是题目要求求出全部知足要求的元组而不限制长度,咱们能够采用回溯法来解决,具体思路为:原来数组中每一个数字都有两种选择,那就是当个好人或者作个卧底,,那就是被选中和不被选中,以此咱们能够来构建二叉树并进行遍历找到知足要求的元组。排序
var sum = function(nums, target) {
let tempNums = nums.slice(),
result = [],
buffer = [],
index = 0,
hash = {}
let _sum = (index, target) => {
if(target === 0 && buffer.length !== 0){
result.push(buffer.slice())
}
if(index === tempNums.length){
return
}
buffer.push(tempNums[index]) // 选中
_sum(index+1, target - tempNums[index])
buffer.pop() // 不选
_sum(index+1, target)
}
_sum(index, target)
// 去重返回
return result.filter(_ => {
_.sort((a, b) => a-b)
if(hash[_] === undefined){
hash[_] = true
return _
}
})
}
复制代码
关于求x个数之和的问题就聊到这里,若有错误,恳请指正👀递归