We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
1262. Greatest Sum Divisible by Three 可被三整除的最大和——中文题解
这道题我思考了很久,觉得挺有意思的。
一开始我就想到要用余数%去排除一些元素。然后我就想着对数组排序,然后找到除以3余数为1的数与除以3余数为2的数配对,为0的数则全部加上。
但问题在于,如何选择?示例3就给了一个很好的例子,[1,2,3,4,4],答案是取[4,4,1],跳过了取2。
然后我又卡了很久,推翻了之前的做法。我想着不如从贪心和余数入手?首先求出所有数字之和,然后分类讨论,假设除以3为0,则直接返回结果;为1,则有两种方式,要么减去一个最小的余数为1的数字,要么减去两个余数为2的数字;为2,同理,两种方式,要么减去一个最小的余数为2的数字,要么减去两个余数为1的数字。
func maxSumDivThree(nums []int) int { ans := 0 sort.Ints(nums) a, b := 0, 0 c, d, cnt1, cnt2 := 0, 0, 0, 0 for i := 0; i < len(nums); i++ { ans += nums[i] if nums[i]%3 == 1 && a == 0 { a = nums[i] } if nums[i]%3 == 2 && b == 0 { b = nums[i] } if nums[i]%3 == 1 && cnt1 < 2 { cnt1++ c += nums[i] } if nums[i]%3 == 2 && cnt2 < 2 { cnt2++ d += nums[i] } } //println(ans, a, b, c, d, cnt1, cnt2) if ans%3 == 1 { t1, t2 := ans, ans if a != 0 { t1 -= a } if cnt2 >= 2 { t2 -= d } if t1 != ans && t2 != ans { ans = max(t1, t2) } else if t1 != ans { ans = t1 } else { ans = t2 } } else if ans%3 == 2 { t1, t2 := ans, ans if b != 0 { t1 -= b } if cnt1 >= 2 { t2 -= c } if t1 != ans && t2 != ans { ans = max(t1, t2) } else if t1 != ans { ans = t1 } else { ans = t2 } } return ans } func max(a, b int) int { if a > b { return a } return b }
既然有关与选择或者选或不选,那么可以用动态规划吗?
问题是,如何定义所有状态?要包含所有状态,所以不妨学习之前01字符串的解法,设长度为3的dp数组,3个位置分别表示余数为0、1、2的最大和。
状态转移:遍历数组,每次加入一个元素,就考虑在这三个状态上更新。这样能够保证每个位置的最大值,达到选择的目的。
func maxSumDivThree(nums []int) int { dp := make([]int, 3) for i := 0; i < len(nums); i++ { a,b,c := dp[0] + nums[i], dp[1] + nums[i], dp[2] + nums[i] dp[a % 3] = max(dp[a % 3], a) dp[b % 3] = max(dp[b % 3], b) dp[c % 3] = max(dp[c % 3], c) } return dp[0] } func max(a, b int) int { if a > b { return a } return b }
动态规划的好处在于,可以由3扩展到更大的数组。所以对于本题,动态规划的思路才是更加通用的做法。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
1262. Greatest Sum Divisible by Three
1262. Greatest Sum Divisible by Three
可被三整除的最大和——中文题解
这道题我思考了很久,觉得挺有意思的。
一开始我就想到要用余数%去排除一些元素。然后我就想着对数组排序,然后找到除以3余数为1的数与除以3余数为2的数配对,为0的数则全部加上。
但问题在于,如何选择?示例3就给了一个很好的例子,[1,2,3,4,4],答案是取[4,4,1],跳过了取2。
一、贪心 + 逆向思维
然后我又卡了很久,推翻了之前的做法。我想着不如从贪心和余数入手?首先求出所有数字之和,然后分类讨论,假设除以3为0,则直接返回结果;为1,则有两种方式,要么减去一个最小的余数为1的数字,要么减去两个余数为2的数字;为2,同理,两种方式,要么减去一个最小的余数为2的数字,要么减去两个余数为1的数字。
二、动态规划
既然有关与选择或者选或不选,那么可以用动态规划吗?
问题是,如何定义所有状态?要包含所有状态,所以不妨学习之前01字符串的解法,设长度为3的dp数组,3个位置分别表示余数为0、1、2的最大和。
状态转移:遍历数组,每次加入一个元素,就考虑在这三个状态上更新。这样能够保证每个位置的最大值,达到选择的目的。
动态规划的好处在于,可以由3扩展到更大的数组。所以对于本题,动态规划的思路才是更加通用的做法。
The text was updated successfully, but these errors were encountered: