文章目录
问题一
问题二
本文主要讲解Java的两道算法题,以及具体的代码实现
给定一个数组(int型),从中选取若干元素,要求所选元素彼此之间均不可相邻(按数组索引判定,首尾元素视为不相邻,数组长度大于2时可同时选取首尾),在所有选取方案中,寻找元素数值总和的最大值。 请实现以下函数,计算最大数值总和,时间复杂度请尽量控制在O(N)(N指代数组长度),空间复杂度请尽量控制在O(1)。 int CalcMaxSum(const vector
& array); 参数说明如下: array: 数组(std::vector ),输入参数。 返回值: 最大数值总和。
这是一个经典的动态规划问题。我们可以使用动态规划来解决。
首先,我们定义一个大小为N的数组dp,其中dp[i]表示从数组的前i个元素中选取若干元素,使得这些元素彼此之间均不可相邻的情况下,所选元素数值总和的最大值。
然后,我们可以根据动态规划的思想,从前往后计算dp数组的值。对于dp[i],有两种选择:
1. 如果选择第i个元素,则不能选择第i-1个元素,因此dp[i] = dp[i-2] + array[i]。
2. 如果不选择第i个元素,则dp[i] = dp[i-1]。
最后,我们返回dp[N-1]作为最大数值总和。
下面是具体的实现代码:
int CalcMaxSum(const vector& array) {
int N = array.size();
if (N == 0) {
return 0;
}
if (N == 1) {
return array[0];
}
if (N == 2) {
return max(array[0], array[1]);
}
vector dp(N, 0);
dp[0] = array[0];
dp[1] = max(array[0], array[1]);
for (int i = 2; i < N; i++) {
dp[i] = max(dp[i-2] + array[i], dp[i-1]);
}
return dp[N-1];
}
该算法的时间复杂度为O(N),空间复杂度为O(N)。但是我们可以优化空间复杂度,只使用常数级别的额外空间。
优化后的实现代码如下:
int CalcMaxSum(const vector& array) {
int N = array.size();
if (N == 0) {
return 0;
}
if (N == 1) {
return array[0];
}
if (N == 2) {
return max(array[0], array[1]);
}
int prev_prev = array[0];
int prev = max(array[0], array[1]);
int curr = 0;
for (int i = 2; i < N; i++) {
curr = max(prev_prev + array[i], prev);
prev_prev = prev;
prev = curr;
}
return curr;
}
这样,算法的空间复杂度就被优化为O(1)了。
int main(int argc, char * argv[])
{
int a[] = { 1,2,3,4,5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
屏幕输出的结果为:
PS:此处给出程序执行的过程步骤,以及最终出现这种结果的算法原理
程序的输出结果为:2,5。
下面是程序执行的过程步骤和出现这种结果的算法原理:
1. 定义一个整数数组a,包含5个元素:1, 2, 3, 4, 5。
2. 声明一个指针ptr,将数组a的地址加1,即指向数组a的下一个位置的地址。
3. 打印输出*(a + 1),即数组a的第2个元素,结果为2。
4. 打印输出*(ptr - 1),即指针ptr的前一个位置的值,由于ptr指向数组a的下一个位置,所以前一个位置即为数组a的最后一个元素,结果为5。
出现这种结果的原因是指针的运算规则和数组的内存布局。在C语言中,指针加1操作会使指针指向下一个相邻的内存位置,而不是加1个字节。数组在内存中是连续存储的,所以&a + 1实际上是指向数组a后面一个位置的地址。因此,ptr指向了数组a的下一个位置。
在输出*(a + 1)时,a + 1表示数组a的第2个元素的地址,然后通过解引用操作符*获取该地址处的值,即为2。
在输出*(ptr - 1)时,ptr - 1表示指针ptr的前一个位置的地址,然后通过解引用操作符*获取该地址处的值,即为5,因为该地址处存储了数组a的最后一个元素。
需要注意的是,这种代码写法存在指针越界的风险,访问超出数组范围的内存可能导致未定义的行为。
配置上述免密登录时,要加入ssh-add命令才能将问题解决
以上就是今天的内容
最后欢迎大家点赞,收藏⭐,转发,
如有问题、建议,请您在评论区留言哦。