首先想到的dfs 好家伙 1500ms。感觉差点就超时了= =。。
dfs总是这样= =。。
func findTargetSumWays(_ nums: [Int], _ target: Int) -> Int {
var res = 0
var sum = 0
let len = nums.count
var tempArray = [Int]()
dfs(0,len,nums, target,&tempArray ,&res,&sum)
return res
}
func dfs(_ index:Int,_ len: Int,_ nums: [Int],_ target: Int, _ tempArray: inout [Int],_ res: inout Int,_ sum: inout Int){
if index == len {
if sum == target {
res += 1
}
return
}
let num = nums[index]
sum += num
tempArray.append(num)
dfs(index + 1, len, nums, target,&tempArray, &res, &sum)
sum -= tempArray.removeLast()
let num1 = -nums[index]
sum += num1
tempArray.append(num1)
dfs(index + 1, len, nums, target,&tempArray, &res, &sum)
sum -= tempArray.removeLast()
}
优化写法
func findTargetSumWays(_ nums: [Int], _ target: Int) -> Int {
var res = 0
let len = nums.count
dfs(0,len,nums, target ,&res,0)
return res
}
func dfs(_ index:Int,_ len: Int,_ nums: [Int],_ target: Int,_ res: inout Int,_ sum:Int){
if index == len {
if sum == target {
res += 1
}
return
}
dfs(index + 1, len, nums, target, &res, sum + nums[index])
dfs(index + 1, len, nums, target, &res, sum - nums[index])
}
另类的dfs
有减枝的快了不少。但还是在300多ms
func findTargetSumWays(_ nums: [Int], _ target: Int) -> Int {
var res = 0
let len = nums.count
var sum = 0
for num in nums {
sum += num
}
dfs(0,len,nums, target ,&res,sum)
return res
}
func dfs(_ index:Int,_ len: Int,_ nums: [Int],_ target: Int,_ res: inout Int,_ sum:Int){
if index == len {
if sum == target {
res += 1
}
return
}
if sum < target {
return
}
dfs(index + 1, len, nums, target, &res, sum )
dfs(index + 1, len, nums, target, &res, sum - 2 * nums[index])
}
开始动态规划0-1背包
如果数组的元素和为sum 添加减号的元素和为 neg ,则剩余加号的元素和为 sum - neg
target = sum - neg - neg
neg = (sum - target) / 2
= =..8ms
func findTargetSumWays(_ nums: [Int], _ target: Int) -> Int {
let len = nums.count
var sum = 0
for num in nums {
sum += num
}
let dif = sum - target
if dif < 0 || dif & 1 != 0 {
return 0
}
let neg = dif / 2
let temp = Array.init(repeating: 0, count: neg + 1)
var dp = Array.init(repeating: temp, count: len + 1)
dp[0][0] = 1
for i in 1...len {
let num = nums[i - 1]
for j in 0...neg {
if j < num {
dp[i][j] = dp[i - 1][j]
}else{
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - num]
}
}
}
return dp[len][neg]
}
一维数组优化 4ms
从高到低遍历 直接逆序的话。有可能会lowwer > heigher = =
要不加判断。要不用 stride 函数
func findTargetSumWays(_ nums: [Int], _ target: Int) -> Int {
var sum = 0
for num in nums {
sum += num
}
let dif = sum - target
if dif < 0 || dif & 1 != 0 {
return 0
}
let neg = dif >> 1
var dp = Array.init(repeating: 0, count: neg + 1)
dp[0] = 1
for num in nums {
for j in stride(from: neg, through: num, by: -1) {
dp[j] += dp[j - num]
}
}
return dp.last!
}