Leetcode 1262. 可被三整除的最大和

题目:给你一个整数数组 nums,请你找出并返回能被三整除的元素最大和。

  示例 1:

  输入:nums = [3,6,5,1,8]
  输出:18
  解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。

  这道题是第163周竞赛的一道题目,难度中等,边学别人的解题方法,边记录吧!

  

方案一、不妨设dp[i] 代表 选取的数字累加和 模3 = i 的数字和  

  假定nums[i] % 3 = 1 ,那么,和 前面选取的数字和模 3 = 2 的数相加,就可以模3为 0 ,表达起来就是 dp[0] = max(dp[0], nums[i] + dp[2])依次类推,只要不断更新 dp 数组即可,注意一点,更新的时候要保存上一个状态的值,避免后续更新的时候重复影响。

  

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5
 6 int maxSumDivThree(vector<int>& nums) {
 7     int dp[3] = { 0, 0, 0 };
 8     int i;
 9     cout << "┌───────┬───────┬───────┐" << endl;
10     for (i = 0; i < nums.size(); i++)
11     {
12         //依次判断nums[i]
13         int mod = nums[i] % 3;
14         int a = dp[(3 + 0 - mod) % 3];//保留上一步的值,避免后续相加影响
15         int b = dp[(3 + 1 - mod) % 3];
16         int c = dp[(3 + 2 - mod) % 3];
17
18         if (a||mod == 0) dp[0] = max(dp[0], a + nums[i]);
19         if (b||mod == 1) dp[1] = max(dp[1], b + nums[i]);
20         if (c||mod == 2) dp[2] = max(dp[2], c + nums[i]);
21         cout << "│\t" << dp[0] << "\t│\t" << dp[1] << "\t│\t" << dp[2] << "\t│" << endl;
22         if(i<nums.size()-1)
23             cout << "├───────┼───────┼───────┤" << endl;
24         else
25             cout << "└───────┴───────┴───────┘" << endl;
26     }
27
28     return dp[0];
29 }
30
31 vector<int> vc;
32 int main()
33 {
34     int n;
35     cin >> n;
36     vc.resize(n);
37     int i;
38     for (i = 0; i < n; i++)
39         cin>>vc[i];
40     cout << endl;
41     cout << "能被3整除的最大和为:" <<maxSumDivThree(vc) << endl;
42     return 0;
43 }

理解:(当然这是看的别人的想法,作者https://leetcode-cn.com/u/igamegum/

  先看下运行结果吧,就用上边的实例进行解释:

  

   1、a,b,c是干什么用的?

  a,b,c应该是保留上一步的值,a、b、c的取值如下:

  

  每次均记录了上一步的dp中的值,下一步在计算dp[0]时,dp[0]会发生变化,此时,在计算dp[1]时,用到的dp[0]不再是原始的dp[0],从而造成数据的不一致问题!

  2、if(b || mod == 1)中,为什么还要判断b的值?

  这里的b我理解的是,当它不为0的时候,不过mod值是不是1,我都需要去更新dp[1],因为存在mod是2,需要考虑(2+2)%3=1的情况,同样,mod为0,需要考虑(1+0)%3=1的情况;这里我们去掉试一试,看下结果:

  

  显然,当计算第4层时,数字1%3=1,此时,dp[0]只考虑了mod=0,所以dp[0]没有进行更新,但是数字1+dp[2]也可以构成模3余0的情况,并且和为15,显然比9大!!!

方案二、国外神代码,没解释,等待理解

 1 class Solution {
 2 public:
 3    int maxSumDivThree(vector<int>& A) {
 4         vector<int> dp = {0, INT_MIN, INT_MIN};
 5         for (int a : A) {
 6             vector<int> dp2 = {0, 0, 0};
 7             for (int i = 0; i < 3; ++i)
 8                 dp2[(i + a) % 3] = max(dp[(i + a) % 3], dp[i] + a);
 9             dp = dp2;
10         }
11         return dp[0];
12     }
13 };

理解了之后回来更新~~~

原文地址:https://www.cnblogs.com/cnyulei/p/11888296.html

时间: 2024-10-25 05:53:21

Leetcode 1262. 可被三整除的最大和的相关文章

LeetCode 15. 3Sum(三数之和)

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: The solution set must not contain duplicate triplets. For example, given array S = [-1,

[leetcode数组系列]2三数之和

前言 秋招的结束,面试了大大小小的公司,最大的问题在于算法上.所以打算坚持在leetcode打卡,看看到底能不能行,如果你想见证,那我来开车,你坐稳,一起走向更好的远方. 在学习今天内容之前,先学习上一篇的两数之和会更好哟 leetcode两数之和求解 一 题目 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满

Binary Tree Inorder Traversal [leetcode] 非递归的三种解法

第一种方法是Morris Traversal 是O(n)时间复杂度,且不需要额外空间的方法.缺点是需要修改树. 通过将叶子节点的right指向其中序后继. 代码如下 vector<int> inorderTraversal(TreeNode *root) { vector<int> res; TreeNode * cur = root; TreeNode * pre = NULL; while (cur) { if (cur->left == NULL) { res.push

[LeetCode] 3Sum Closest 最近三数之和

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-1 2

[leetcode]75.Sort Color三指针

import java.util.Arrays; /** * Given an array with n objects colored red,white or blue, * sort them so that objects of the same color are adjacent, * with the colors in the order red, white and blue. Here, we will use the integers 0, 1, and 2 to repr

LeetCode第15题 三数之和

/* 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]*/ /* 思路: 首先想到的肯定是穷举,时间复杂度为O(n^3) , 但如果使用这种方法,也实在称不上算法题了,果不其然,超时. [

Leetcode 1022. 可被 K 整除的最小整数

1022. 可被 K 整除的最小整数 显示英文描述 我的提交返回竞赛 用户通过次数74 用户尝试次数262 通过次数75 提交次数1115 题目难度Medium 给定正整数 K,你需要找出可以被 K 整除的.仅包含数字 1 的最小正整数 N. 返回 N 的长度.如果不存在这样的 N,就返回 -1. 示例 1: 输入:1 输出:1 解释:最小的答案是 N = 1,其长度为 1. 示例 2: 输入:2 输出:-1 解释:不存在可被 2 整除的正整数 N . 示例 3: 输入:3 输出:3 解释:最小

Leetcode 1029. 可被 5 整除的二进制前缀

1029. 可被 5 整除的二进制前缀 显示英文描述 我的提交返回竞赛 用户通过次数467 用户尝试次数662 通过次数477 提交次数1964 题目难度Easy 给定由若干 0 和 1 组成的数组 A.我们定义 N_i:从 A[0] 到 A[i] 的第 i 个子数组被解释为一个二进制数(从最高有效位到最低有效位). 返回布尔值列表 answer,只有当 N_i 可以被 5 整除时,答案 answer[i] 为 true,否则为 false. 示例 1: 输入:[0,1,1] 输出:[true,

关于LeetCode解题提升(三)

今天遇到一道DP题,记录一下思路,以免遗忘. 题目:地下城游戏 题目来源:https://leetcode-cn.com/problems/dungeon-game/ 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. 骑士的初始健康点数为一个正整数.如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡. 有些房间由恶魔守卫,因此骑士在进入这些房间时会失去