给你一个整数数组 nums
和两个整数 firstLen
和 secondLen
,请你找出并返回两个非重叠 子数组 中元素的最大和,长度分别为 firstLen
和 secondLen
。
长度为 firstLen
的子数组可以出现在长为 secondLen
的子数组之前或之后,但二者必须是不重叠的。
子数组是数组的一个 连续 部分。
示例 1:
输入:nums = [0,6,5,2,2,5,1,9,4], firstLen = 1, secondLen = 2 输出:20 解释:子数组的一种选择中,[9] 长度为 1,[6,5] 长度为 2。
示例 2:
输入:nums = [3,8,1,3,2,1,8,9,0], firstLen = 3, secondLen = 2 输出:29 解释:子数组的一种选择中,[3,8,1] 长度为 3,[8,9] 长度为 2。
示例 3:
输入:nums = [2,1,5,6,0,9,5,0,3,8], firstLen = 4, secondLen = 3 输出:31 解释:子数组的一种选择中,[5,6,0,9] 长度为 4,[0,3,8] 长度为 3。
提示:
1 <= firstLen, secondLen <= 1000
2 <= firstLen + secondLen <= 1000
firstLen + secondLen <= nums.length <= 1000
0 <= nums[i] <= 1000
这个题目比较经典,挖掘关键信息:「两个」、「不重叠」、「子数组」。
立即推,枚举分割点,即分割点左边是
L
时,右边则为M
,反之亦然。使用前缀和维护分割点两边的定长子数组最大和即可。
但是官方给的思路是:
inline int max(int a, int b) {
return a > b ? a : b;
}
int help(const int* nums, int numsSize, int firstLen, int secondLen) {
int suml = 0;
for (int i = 0; i < firstLen; i++) {
suml += nums[i];
}
int maxSumL = suml;
int sumr = 0;
for (int i = firstLen; i < firstLen + secondLen; i++) {
sumr += nums[i];
}
int res = maxSumL + sumr;
for (int i = firstLen + secondLen, j = firstLen; i < numsSize; ++i, ++j) {
suml += nums[j] - nums[j - firstLen];
maxSumL = max(maxSumL, suml);
sumr += nums[i] - nums[i - secondLen];
res = max(res, maxSumL + sumr);
}
return res;
}
int maxSumTwoNoOverlap(int* nums, int numsSize, int firstLen, int secondLen) {
return max(help(nums, numsSize, firstLen, secondLen), help(nums, numsSize, secondLen, firstLen));
}
那就把它当作板子题,记一下吧!
java的学习
经典hello,word!
/*
*第一个Java程序
*/
public class Main{
public static void main(String[] args) {
System.out.println("hello,word!");
}
}
java的一些知识点
数据类型:boolean、int、long、short、byte、float、double、char、class、interface。
流程控制:if、else、do、while、for、switch、case、default、break、continue、return、try、catch、finally。
修饰符:public、protected、private、final、void、static、strict、abstract、transient、synchronized、volatile、native。
动作:package、import、throw、throws、extends、implements、this、supper、instanceof、new。
保留字:true、false、null、goto、const。
特别的注释:
文档注释:
以/**打头,以*/结束,不同于段注释,文档注释会将/**和*/之间的内容归档与javadoc中,在生成Html报告中被识别显示出来,用于记录程序信息
复习数据结构
dfs 板子
bool check(参数)
{
if(满足条件)
return true ;
return false;
}
void dfs(int step)
{
判断边界
{
相应操作
}
尝试每一种可能
{
满足check条件
标记
继续下一步dfs(step+1)
恢复初始状态(回溯的时候要用到)
}
}
哈夫曼树的实现:
//HT为地址传递的存储哈夫曼树的数组,w为存储结点权重值的数组,n为结点个数
void CreateHuffmanTree(HuffmanTree *HT, int *w, int n) {
if(n <= 1)
return; // 如果只有一个编码就相当于0
int m = 2*n-1; // 哈夫曼树总节点数,n就是叶子结点
*HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0号位置不用
HuffmanTree p = *HT;
// 初始化哈夫曼树中的所有结点
for(int i = 1; i <= n; i++) {
(p+i)->weight = *(w+i-1);
(p+i)->parent = 0;
(p+i)->left = 0;
(p+i)->right = 0;
}
//从树组的下标 n+1 开始初始化哈夫曼树中除叶子结点外的结点
for(int i = n+1; i <= m; i++) {
(p+i)->weight = 0;
(p+i)->parent = 0;
(p+i)->left = 0;
(p+i)->right = 0;
}
//构建哈夫曼树
for(int i = n+1; i <= m; i++) {
int s1, s2;
Select(*HT, i-1, &s1, &s2); //查找内容,需要用到查找算法
(*HT)[s1].parent = (*HT)[s2].parent = i;
(*HT)[i].left = s1;
(*HT)[i].right = s2;
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
}
}