給定一個包含
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個數之和的問題就聊到這裏,若有錯誤,懇請指正👀遞歸