1 func largestSumAfterKNegations(A []int, K int) int { 2 sort.Ints(A) 3 var negatives int 4 var zeros int 5 var positives int 6 var negativeAry []int 7 var positiveAry []int 8 for n := range A { 9 if A[n] < 0 { 10 negatives++ 11 negativeAry = append(negativeAry, A[n]) 12 } else if A[n] == 0 { 13 zeros++ 14 } else { 15 positives++ 16 positiveAry = append(positiveAry, A[n]) 17 } 18 } 19 var sum int 20 if K <= negatives { //只需要把负数变正数,把最小的(绝对值大的)K个负数变正数 21 for i := 0; i < K; i++ { 22 sum += negativeAry[i] * -1 23 } 24 for i := K; i < negatives; i++ { 25 sum += negativeAry[i] 26 } 27 for i := 0; i < positives; i++ { 28 sum += positiveAry[i] 29 } 30 } else { //将全部的负数都变成正数,还不够 31 if zeros > 0 || (K-negatives)%2 == 0 { 32 //剩下的变化次数,全变0,或者反复的变偶数次同一个正数(也可以是一个已经变成正数的负数) 33 for i := 0; i < negatives; i++ { 34 sum += negativeAry[i] * -1 35 } 36 for i := 0; i < positives; i++ { 37 sum += positiveAry[i] 38 } 39 } else { 40 //先把负数的绝对值累加 41 for i := 0; i < negatives; i++ { 42 sum += negativeAry[i] * -1 43 } //再把正数的绝对值累加 44 for i := 0; i < positives; i++ { 45 sum += positiveAry[i] 46 } //判断全部已经都变成正数的数组中,绝对值最小的数字 47 //将绝对值最小的这个数字,减2次 48 if (negatives == 0 && positives > 0) || (positives > 0 && negatives > 0 && positiveAry[0] <= negativeAry[negatives-1]*-1) { 49 sum += positiveAry[0] * -2 50 return sum 51 } 52 if (positives == 0 && negatives > 0) || (positives > 0 && negatives > 0 && positiveAry[0] > negativeAry[negatives-1]*-1) { 53 sum += negativeAry[negatives-1] * 2 54 return sum 55 } 56 } 57 58 } 59 return sum 60 }
上面这个一定觉得很啰嗦,那就来个简单的:
1 func largestSumAfterKNegations(A []int, K int) int { 2 sort.Ints(A) 3 i := 0 4 for i < len(A) && K > 0 && A[i] < 0 { 5 A[i] = -A[i] 6 i++ 7 K-- 8 } 9 sum := 0 10 sort.Ints(A) 11 for j := range A { 12 sum += A[j] 13 } 14 if K > 0 && K%2 == 1 { 15 min := A[0] 16 sum -= min * 2 17 } 18 return sum 19 }
思想是一样的,但是简洁了很多。而且由于没有使用新数组保存正和负数,所以空间占用更小。
第一部分代码是思维的过程,第二部分代码是提炼之后的。leetcode上面的题目,大部分都可以用20,30行就搞定。如果代码特别长,那应该是没有抓住问题的本质,这样的代码思维可能把自己绕进去,别人看不懂,甚至自己也会看迷糊。
最后,go的效率的确是棒棒的: