题目链接
思路:状态转移
分析:题目的意思就是从数组中挑选出来一些数字,这些数加起来的和,除以3能正好整除,并且这个和要最大。
一个数除3的余数一共三种情况,state[0],state[1],state2
那么可以根据这三种情况遍历数组,分析出来如下:
- 如果当前数字除3余0,那么就可以直接加到3中状态中,因为这种情况是不会影响整体情况的。
- 如果当前数字除3余1,那么
2.1 state[0]应该更新为state[0]和state[2]+当前数字,因为余数为2的加上余数为1的,整体就是余数为0的,所以state[0]应该取之前的和当前的最大。
2.2 state[1] 应该更新为state[1]和state[0]+当前数字,同理,余数为0的加上余数为1的,整体就是余数为1的,所以state[1]应该取之前和最大和当前的最大。
2.3 state[2]应该更新为 state[2]和stat[1]+当前数字,同理。 - 如果当前数字除3 余2,那么也是相同原理进行状态转移。
代码:
class Solution {
public int maxSumDivThree(int[] nums) {
int[] state = new int[3];
//这是必须的,因为state[1] state[2]只有在有数字不能整除3才会用到,所以一开始数字整除3的时候,state[1] state[2]必须是极小的数字,才不会影响到后面的状态转移。
state[1] = Integer.MIN_VALUE;
state[2] = Integer.MIN_VALUE;
int tem0,tem1,tem2;
for(int num : nums){
if((num%3)==0){
state[0]+=num;
state[1]+=num;
state[2]+=num;
continue;
}else if((num%3)==1){
tem0 = Math.max(state[0], state[2] + num);
tem1 = Math.max(state[1], state[0] + num);
tem2 = Math.max(state[2], state[1] + num);
}else{
tem0 = Math.max(state[0], state[1] + num);
tem1 = Math.max(state[1], state[2] + num);
tem2 = Math.max(state[2], state[0] + num);
}
state[0] = tem0;
state[1] = tem1;
state[2] = tem2;
}
return state[0];
}
}
这里有个细节要注意:计算的时候需使用到tem,而不能直接每次计算max都直接更新state,因为后面计算还需要使用到上一轮的state,所以必须是一轮计算完统一进行状态转移。
好好学习。
不打扰是我的温柔。