2011. 执行操作后的变量值
存在一种仅支持 4 种操作和 1 个变量 X
的编程语言:
++X
和X++
使变量X
的值 加1
--X
和X--
使变量X
的值 减1
最初,X
的值是 0
给你一个字符串数组 operations
,这是由操作组成的一个列表,返回执行所有操作后,X
的 最终值 。
示例 1:
输入:operations = ["--X","X++","X++"]
输出:1
解释:操作按下述步骤执行:
最初,X = 0
--X:X 减 1 ,X = 0 - 1 = -1
X++:X 加 1 ,X = -1 + 1 = 0
X++:X 加 1 ,X = 0 + 1 = 1
示例 2:
输入:operations = ["++X","++X","X++"]
输出:3
解释:操作按下述步骤执行:
最初,X = 0
++X:X 加 1 ,X = 0 + 1 = 1
++X:X 加 1 ,X = 1 + 1 = 2
X++:X 加 1 ,X = 2 + 1 = 3
示例 3:
输入:operations = ["X++","++X","--X","X--"]
输出:0
解释:操作按下述步骤执行:
最初,X = 0
X++:X 加 1 ,X = 0 + 1 = 1
++X:X 加 1 ,X = 1 + 1 = 2
--X:X 减 1 ,X = 2 - 1 = 1
X--:X 减 1 ,X = 1 - 1 = 0
提示:
1 <= operations.length <= 100
operations[i]
将会是"++X"
、"X++"
、"--X"
或"X--"
cpp
#include <stdio.h>
// 函数声明:计算最终的x值
// 参数:operations - 操作数组,每个元素是一个字符串操作
// operationsSize - 操作的数量
// 返回:最终的x值
int finalValueAfterOperations(char** operations, int operationsSize) {
int x = 0; // 初始化x为0
for (int i = 0; i < operationsSize; ++i) { // 遍历每个操作
// 检查操作的第二个字符是否为'+',如果是则x加1,否则x减1
if (*(*(operations + i) + 1) == '+') {
x++;
} else {
x--;
}
}
return x; // 返回最终的x值
}
int main() {
// 定义并初始化一个包含三个操作的数组
char* operations[100] = {"--X", "X++", "X++"};
// 调用函数并打印结果
printf("%d ", finalValueAfterOperations(operations, 3));
return 0;
}
1929. 数组串联
给你一个长度为 n
的整数数组 nums
。请你构建一个长度为 2n
的答案数组 ans
,数组下标从 0 开始计数 ,对于所有 0 <= i < n
的 i
,满足下述所有要求:
ans[i] == nums[i]
ans[i + n] == nums[i]
具体而言,ans
由两个 nums
数组 串联 形成。
返回数组ans
。
示例 1:
输入:nums = [1,2,1]
输出:[1,2,1,1,2,1]
解释:数组 ans 按下述方式形成:
- ans = [nums[0],nums[1],nums[2],nums[0],nums[1],nums[2]]
- ans = [1,2,1,1,2,1]
示例 2:
输入:nums = [1,3,2,1]
输出:[1,3,2,1,1,3,2,1]
解释:数组 ans 按下述方式形成:
- ans = [nums[0],nums[1],nums[2],nums[3],nums[0],nums[1],nums[2],nums[3]]
- ans = [1,3,2,1,1,3,2,1]
提示:
n == nums.length
1 <= n <= 1000
1 <= nums[i] <= 1000
cpp
#include <stdio.h>
#include <cstdlib>
int* getConcatenation(int* nums, int numsSize, int* returnSize) {
*returnSize = numsSize*2;
int* ans = (int*) malloc(*returnSize * sizeof (int));
if (ans == NULL){
exit(1);
}
for (int i = 0; i < numsSize; ++i) {
ans[i] = nums[i];
ans[i+numsSize] = nums[i];
}
return ans;
}
int main() {
int nums[3]= {1,2,1};
int returnSize = 0;
int* ans = getConcatenation(nums,3,&returnSize);
for (int i = 0; i < returnSize; ++i) {
printf("%d ",ans[i]);
}
return 0;
}
1720. 解码异或后的数组
未知 整数数组 arr
由 n
个非负整数组成。
经编码后变为长度为 n - 1
的另一个整数数组 encoded
,其中 encoded[i] = arr[i] XOR arr[i + 1]
。例如,arr = [1,0,2,1]
经编码后得到 encoded = [1,2,3]
。
给你编码后的数组 encoded
和原数组 arr
的第一个元素 first
(arr[0]
)。
请解码返回原数组 arr
。可以证明答案存在并且是唯一的。
示例 1:
输入:encoded = [1,2,3], first = 1
输出:[1,0,2,1]
解释:若 arr = [1,0,2,1] ,那么 first = 1 且 encoded = [1 XOR 0, 0 XOR 2, 2 XOR 1] = [1,2,3]
示例 2:
输入:encoded = [6,2,7,3], first = 4
输出:[4,2,0,7,4]
提示:
2 <= n <= 104
encoded.length == n - 1
0 <= encoded[i] <= 105
0 <= first <= 105
cpp
#include <cstdio> // 包含标准输出函数 printf 的头文件
#include <cstdlib> // 包含动态内存分配函数 malloc 的头文件
int* decode(int* encoded, int encodedSize, int first, int* returnSize) {
// 计算解码后数组的大小,即编码数组的大小 + 1
*returnSize = encodedSize + 1;
// 动态分配内存,用于存储解码后的数组
int* ans = (int*)malloc(*returnSize * sizeof(int));
// 初始化第一个元素为 first
int i = 0;
ans[i] = first;
// 根据编码数组解码后续元素
while (i + 1 <= encodedSize) {
// 运用异或运算解码:ans[i+1] = ans[i] ^ encoded[i]
ans[i + 1] = ans[i] ^ encoded[i];
i++;
}
// 返回解码后的数组
return ans;
}
int main() {
// 定义一个编码数组
int encoded[3] = {1, 2, 3};
// 定义返回的大小
int returnSize;
// 调用 decode 函数解码数组
int* ans = decode(encoded, 3, 1, &returnSize);
// 打印解码后的数组
for (int i = 0; i < returnSize; ++i) {
printf("%d ", ans[i]);
}
// 通常需要释放动态分配的内存,但在此示例中没有提供 free 代码(仅演示)
// free(ans);
return 0; // 程序结束,返回 0
}
![](https://i-blog.csdnimg.cn/direct/3b53f48dd70749f888a8a714fe16e801.png)
2574. 左右元素和的差值
给你一个下标从 0 开始的整数数组 nums
,请你找出一个下标从 0 开始的整数数组 answer
,其中:
answer.length == nums.length
answer[i] = |leftSum[i] - rightSum[i]|
其中:
leftSum[i]
是数组nums
中下标i
左侧元素之和。如果不存在对应的元素,leftSum[i] = 0
。rightSum[i]
是数组nums
中下标i
右侧元素之和。如果不存在对应的元素,rightSum[i] = 0
。
返回数组 answer
。
示例 1:
输入:nums = [10,4,8,3]
输出:[15,1,11,22]
解释:数组 leftSum 为 [0,10,14,22] 且数组 rightSum 为 [15,11,3,0] 。
数组 answer 为 [|0 - 15|,|10 - 11|,|14 - 3|,|22 - 0|] = [15,1,11,22] 。
示例 2:
输入:nums = [1]
输出:[0]
解释:数组 leftSum 为 [0] 且数组 rightSum 为 [0] 。
数组 answer 为 [|0 - 0|] = [0] 。
方式一,直接循环加循环哈哈
cpp
#include <cstdio>
#include <cstdlib>
#include <cmath>
int* leftRightDifference(int* nums, int numsSize, int* returnSize) {
*returnSize = numsSize;
int* ans = (int*) malloc(*returnSize*sizeof (int ));
int l = 0,r = 0,leftSum = 0,rightSum = 0;
for (int i = 0; i < numsSize; ++i) {
l = i-1;
while (true){
if (l < 0){
leftSum += 0;
break;
} else {
leftSum += nums[l--];
}
}
r = i+1;
while (true){
if (r>=numsSize){
rightSum += 0;
break;
} else{
rightSum+=nums[r++];
}
}
ans[i] = abs((leftSum-rightSum));
rightSum = 0;
leftSum = 0;
}
return ans;
}
int main() {
int nums[4] = {10,4,8,3};
int returnSize = 4;
int* ans = leftRightDifference(nums,4,&returnSize);
for (int i = 0; i < returnSize; ++i) {
printf("%d ",ans[i]);
}
return 0;
}
大佬们写的
cpp
#include <cstdio> // 包含标准输出函数 printf 的头文件
#include <cstdlib> // 包含动态内存分配函数 malloc、abs 的头文件
int* leftRightDifference(int* nums, int numsSize, int* returnSize) {
*returnSize = numsSize; // 设置返回数组的大小,与输入数组大小相同
// 动态分配内存,用于存储结果数组
int* ans = (int*)malloc(*returnSize * sizeof(int));
// 计算输入数组的总和
int sum = 0;
for (int i = 0; i < numsSize; ++i) {
sum += nums[i]; // 累加数组元素之和
}
int left = 0; // 初始化左侧元素之和
for (int j = 0; j < numsSize; ++j) {
// 计算右侧元素之和:总和 - 当前元素 - 左侧元素之和
int right = sum - nums[j] - left;
// 计算左右侧和的绝对差,并存储到结果数组
ans[j] = abs(left - right);
// 累加当前元素到左侧元素之和,用于下一个元素的计算
left += nums[j];
}
return ans; // 返回结果数组
}
int main() {
int nums[4] = {10,4,8,3}; // 输入数组
int returnSize = 4; // 返回数组的大小
// 调用 leftRightDifference 函数,传入输入数组和返回大小的指针
int* ans = leftRightDifference(nums,4,&returnSize);
// 打印结果数组
for (int i = 0; i < returnSize; ++i) {
printf("%d ", ans[i]);
}
// 释放动态分配的内存(在实际项目中应该释放,但在此示例中未提供)
// free(ans);
return 0; // 程序结束,返回 0
}
1365. 有多少小于当前数字的数字
给你一个数组 nums
,对于其中每个元素 nums[i]
,请你统计数组中比它小的所有数字的数目。
换而言之,对于每个 nums[i]
你必须计算出有效的 j
的数量,其中 j
满足 j != i
且 nums[j] < nums[i]
。
以数组形式返回答案。
示例 1:
输入:nums = [8,1,2,2,3]
输出:[4,0,1,1,3]
解释:
对于 nums[0]=8 存在四个比它小的数字:(1,2,2 和 3)。
对于 nums[1]=1 不存在比它小的数字。
对于 nums[2]=2 存在一个比它小的数字:(1)。
对于 nums[3]=2 存在一个比它小的数字:(1)。
对于 nums[4]=3 存在三个比它小的数字:(1,2 和 2)。
示例 2:
输入:nums = [6,5,4,8]
输出:[2,1,0,3]
示例 3:
输入:nums = [7,7,7,7]
输出:[0,0,0,0]
提示:
2 <= nums.length <= 500
0 <= nums[i] <= 100
cpp
#include <cstdio> // 包含标准输出函数 printf 的头文件
#include <cstdlib> // 包含动态内存分配函数 malloc 的头文件
int* smallerNumbersThanCurrent(int* nums, int numsSize, int* returnSize) {
*returnSize = numsSize; // 设置返回数组的大小为输入数组大小
// 动态分配内存用于存储结果数组
int* ans = (int*)malloc(*returnSize * sizeof(int));
int count = 0; // 用于计数比当前元素小的数目
// 遍历每个元素
for (int i = 0; i < numsSize; ++i) {
int current = nums[i]; // 获取当前元素
// 遍历整个数组,统计比当前元素小的数目
for (int j = 0; j < numsSize; ++j) {
if (current > nums[j]) {
count++; // 遇到比当前元素小的元素,计数加一
}
}
// 将计数结果存入结果数组
ans[i] = count;
// 重置计数器,准备下一个元素的统计
count = 0;
}
return ans; // 返回结果数组
}
int main() {
int nums[4] = {6,5,4,8}; // 输入数组
int returnSize = 4; // 返回数组的大小
// 调用函数,并获取结果数组
int* ans = smallerNumbersThanCurrent(nums, 4, &returnSize);
// 打印结果数组
for (int i = 0; i < returnSize; ++i) {
printf("%d ", ans[i]);
}
// 释放动态分配的内存
free(ans);
return 0; // 程序结束,返回 0
}
1732. 找到最高海拔
有一个自行车手打算进行一场公路骑行,这条路线总共由 n + 1
个不同海拔的点组成。自行车手从海拔为 0
的点 0
开始骑行。
给你一个长度为 n
的整数数组 gain
,其中 gain[i]
是点 i
和点 i + 1
的 净海拔高度差 (0 <= i < n
)。请你返回 最高点的海拔 。
示例 1:
输入:gain = [-5,1,5,0,-7]
输出:1
解释:海拔高度依次为 [0,-5,-4,1,1,-6] 。最高海拔为 1 。
示例 2:
输入:gain = [-4,-3,-2,-1,4,3,2]
输出:0
解释:海拔高度依次为 [0,-4,-7,-9,-10,-6,-3,-1] 。最高海拔为 0 。
提示:
n == gain.length
1 <= n <= 100
-100 <= gain[i] <= 100
cpp
#include <cstdio> // 包含标准输出函数 printf 的头文件
#include <cstdlib> // 包含动态内存分配函数 malloc 的头文件
int largestAltitude(int* gain, int gainSize) {
int ansSize = gainSize + 1; // 海拔数组的大小(起点海拔加上每一步的净高度差)
int* ans = (int*)malloc(ansSize * sizeof(int)); // 动态分配内存存储海拔数组
ans[0] = 0; // 初始化起点海拔为 0
int max = 0; // 初始化最高海拔为 0
// 计算每个点的海拔高度,并跟踪最大值
for (int i = 1; i < ansSize; ++i) {
ans[i] = ans[i - 1] + gain[i - 1]; // 当前海拔 = 前一点海拔 + 当前净高度差
if (max < ans[i]) { // 如果当前海拔高于当前最大值,更新最大值
max = ans[i];
}
}
free(ans);// 释放内存
return max; // 返回最高海拔高度
}
int main() {
int nums[5] = {-5, 1, 5, 0, -7}; // 输入的净海拔高度差数组
printf("%d\n", largestAltitude(nums, 5)); // 调用函数并打印最高海拔高度值
return 0; // 程序结束,
![](https://i-blog.csdnimg.cn/direct/462419a315c84dd6a4cefae599a62487.png)
1464. 数组中两元素的最大乘积
给你一个整数数组 nums
,请你选择数组的两个不同下标 i
和 j
, 使 (nums[i]-1)*(nums[j]-1)
取得最大值。
请你计算并返回该式的最大值。
示例 1:
输入:nums = [3,4,5,2]
输出:12
解释:如果选择下标 i=1 和 j=2(下标从 0 开始),则可以获得最大值,(nums[1]-1)*(nums[2]-1) = (4-1)*(5-1) = 3*4 = 12 。
示例 2:
输入:nums = [1,5,4,5]
输出:16
解释:选择下标 i=1 和 j=3(下标从 0 开始),则可以获得最大值 (5-1)*(5-1) = 16 。
示例 3:
输入:nums = [3,7]
输出:12
提示:
2 <= nums.length <= 500
1 <= nums[i] <= 10^3
cpp
#include <cstdio> // 包含标准输入输出头文件
// 其实就是找最大的两个数
int maxProduct(int* nums, int numsSize) {
int low, high, mid, temp; // 定义辅助变量用于排序过程
// 使用插入排序(基于二分查找的优化)对数组进行升序排序
for (int i = 1; i < numsSize; ++i) {
low = 0; // 初始比较范围左边界
high = i - 1; // 初始比较范围右边界
temp = nums[i]; // 待插入元素
// 使用二分查找确定插入位置
while (low <= high) {
mid = (low + high) / 2; // 中间位置
if (nums[mid] > temp) { // 如果中间元素大于待插入元素
low = mid + 1; // 插入位置应在中间位置右侧
} else { // 如果中间元素小于或等于待插入元素
high = mid - 1; // 插入位置应在中间位置左侧
}
}
// 将插入位置后的元素向后移动一位,为待插入元素腾出空间
for (int j = i - 1; j >= low; --j) {
nums[j + 1] = nums[j];
}
// 将待插入元素放入正确的位置
nums[low] = temp;
}
// 排序完成后,数组前两个元素是最大的两个元素
// 返回这两个元素(每个元素减一后的乘积)
return (nums[0] - 1) * (nums[1] - 1);
}
int main() {
int nums[4] = {3,4,5,2}; // 输入数组
printf("%d ", maxProduct(nums, 4)); // 调用函数并打印结果
return 0; // 程序结束,返回 0
}
2496. 数组中字符串的最大值
一个由字母和数字组成的字符串的 值 定义如下:
- 如果字符串 只 包含数字,那么值为该字符串在
10
进制下的所表示的数字。 - 否则,值为字符串的 长度。
给你一个字符串数组 strs
,每个字符串都只由字母和数字组成,请你返回 strs
中字符串的 最大值 。
示例 1:
输入:strs = ["alic3","bob","3","4","00000"]
输出:5
解释:
- "alic3" 包含字母和数字,所以值为长度 5 。
- "bob" 只包含字母,所以值为长度 3 。
- "3" 只包含数字,所以值为 3 。
- "4" 只包含数字,所以值为 4 。
- "00000" 只包含数字,所以值为 0 。
所以最大的值为 5 ,是字符串 "alic3" 的值。
示例 2:
输入:strs = ["1","01","001","0001"]
输出:1
解释:
数组中所有字符串的值都是 1 ,所以我们返回 1 。
提示:
1 <= strs.length <= 100
1 <= strs[i].length <= 9
strs[i]
只包含小写英文字母和数字。
cpp
#include <cstdio> // 包含标准输入输出头文件
#include <cstdlib>
#include <cstring>
// 定义一个函数,返回字符串数组中的最大值
int maximumValue(char** strs, int strsSize) {
int max = 0; // 初始化最大值为0
for (int i = 0; i < strsSize; ++i) { // 遍历每一个字符串
bool flag = true; // 标志位,标记当前字符串是否全为数字
// 遍历字符串中的每一个字符,判断是否全为数字
for (int j = 0; j < strlen(strs[i]); ++j) {
if (!(strs[i][j] >= '0' && strs[i][j] <= '9')) { // 如果字符不是数字
flag = false; // 标记当前字符串存在非数字字符
break; // 退出字符检查循环
} else {
flag = true; // 当前字符是数字,继续保持标记为真
}
}
// 根据flag判断当前字符串是否全为数字
if (flag) { // 如果全部是数字
// 将字符串转换为整数,并比较大小
if (atoi(strs[i]) > max) {
max = atoi(strs[i]); // 更新最大值
}
} else { // 如果存在非数字字符
// 比较字符串的长度
int currentLength = strlen(strs[i]);
if (currentLength > max) {
max = currentLength; // 更新最大值
}
}
}
return max; // 返回计算得到的最大值
}
int main() {
char strs[4][9] = {"1","01","001","0001"}; // 定义一个二维字符数组,初始化为4个字符串
// 创建一个指针数组,用于存放字符数组的指针
char** point = (char **) malloc(5 * sizeof(char *)); // 动态分配内存
// 将二维字符数组中的每个字符串的地址赋值给指针数组
for (int i = 0; i < 4; ++i) {
point[i] = strs[i];
}
// 调用 maximumValue 函数,并打印结果
printf("%d ", maximumValue(point, 4));
return 0; // 程序结束,返回0
}
1979. 找出数组的最大公约数
给你一个整数数组 nums
,返回数组中最大数和最小数的 最大公约数 。
两个数的 最大公约数 是能够被两个数整除的最大正整数。
示例 1:
输入:nums = [2,5,6,9,10]
输出:2
解释:
nums 中最小的数是 2
nums 中最大的数是 10
2 和 10 的最大公约数是 2
示例 2:
输入:nums = [7,5,6,8,3]
输出:1
解释:
nums 中最小的数是 3
nums 中最大的数是 8
3 和 8 的最大公约数是 1
示例 3:
输入:nums = [3,3]
输出:3
解释:
nums 中最小的数是 3
nums 中最大的数是 3
3 和 3 的最大公约数是 3
提示:
2 <= nums.length <= 1000
1 <= nums[i] <= 1000
cpp
#include <cstdio> // 包含标准输入输出头文件,用于printf等函数
// 定义一个函数findGCD,用于计算数组中所有整数的最大公约数(GCD)
// 参数:nums - 指向整数数组的指针;numsSize - 数组的大小
int findGCD(int* nums, int numsSize) {
// 初始化max和min为数组的第一个元素
int max = *nums;
int min = *nums;
// 遍历数组,找到最大值和最小值
for (int i = 0; i < numsSize; ++i) {
// 如果当前元素大于max,则更新max
if (max < *(nums + i)) {
max = *(nums + i);
}
// 如果当前元素小于min,则更新min
if (min > *(nums + i)) {
min = *(nums + i);
}
}
// 使用更相减损术计算最大公约数
// 更相减损术:通过不断减去较小数来找到两个数的最大公约数
while (min != max) {
// 如果max大于min,将max减去min
if (max > min) {
max -= min;
} else {
// 否则,将min减去max
min -= max;
}
}
// 返回计算得到的最大公约数
return max;
}
// 程序的主函数
int main() {
// 定义一个整数数组nums,并初始化
int nums[5] = {2, 5, 6, 9, 10};
// 调用findGCD函数,计算数组的最大公约数,并打印结果
printf("%d ", findGCD(nums, 5));
// 程序结束,返回0
return 0;
}
485. 最大连续 1 的个数
给定一个二进制数组 nums
, 计算其中最大连续 1
的个数。
示例 1:
输入:nums = [1,1,0,1,1,1]
输出:3
解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
示例 2:
输入:nums = [1,0,1,1,0,1]
输出:2
提示:
1 <= nums.length <= 105
nums[i]
不是0
就是1
.
cpp
#include <cstdio> // 包含标准输入输出头文件,用于使用printf等函数
// 定义一个函数,用于找到数组中连续1的最大数量
int findMaxConsecutiveOnes(int* nums, int numsSize) {
int maxCount = 0; // 记录最大连续1的数量
int currentCount = 0; // 记录当前连续1的数量
// 遍历数组中的每一个元素
for (int i = 0; i < numsSize; ++i) {
if (nums[i] == 1) {
currentCount++; // 当前元素为1,增加当前连续1的数量
} else {
currentCount = 0; // 当前元素不为1,重置当前连续1的数量
}
// 如果当前连续1的数量大于最大连续1的数量,则更新最大值
if (currentCount > maxCount) {
maxCount = currentCount;
}
}
return maxCount; // 返回最大连续1的数量
}
int main() {
int nums[6] = {1, 1, 1, 1, 1, 1}; // 定义一个包含6个1的整数数组
printf("%d ", findMaxConsecutiveOnes(nums, 6)); // 调用函数并打印结果
return 0; // 程序结束,返回0
}
414. 第三大的数
给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。
示例 1:
输入:[3, 2, 1]
输出:1
解释:第三大的数是 1 。
示例 2:
输入:[1, 2]
输出:2
解释:第三大的数不存在, 所以返回最大的数 2 。
示例 3:
输入:[2, 2, 3, 1]
输出:1
解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。
此例中存在两个值为 2 的数,它们都排第二。在所有不同数字中排第三大的数为 1 。
cpp
#include <cstdio> // 包含标准输入输出头文件
// 函数:找到数组中的第三大数
int thirdMax(int* nums, int numsSize) {
// 归并排序(从大到小)
int high, mid, low, temp; // 定义变量用于排序
for (int i = 1; i < numsSize; ++i) { // 遍历数组,从第二个元素开始
low = 0; // 初始的低位指针
high = i - 1; // 初始的高位指针
temp = nums[i]; // 保存当前元素的值
// 使用二分查找确定插入位置
while (low <= high) {
mid = (high + low) / 2; // 计算中间位置
if (nums[mid] > temp) {
low = mid + 1; // 如果中间元素大于当前元素,调整低位指针
} else {
high = mid - 1; // 否则,调整高位指针
}
}
// 将插入位置后的元素向右移动
for (int j = i - 1; j >= low; --j) {
nums[j + 1] = nums[j]; // 元素右移
}
nums[low] = temp; // 将当前元素插入正确位置
}
// 查找第三大数
int prev = nums[0]; // 用于记录前一个不同的数字
int count = 1; // 记录不同数字的数量,默认已有一个最大的数
int third_largest = 0; // 用于存储第三大的数字
// 遍历排序后的数组,统计不同数字的数量
for (int i = 1; i < numsSize; ++i) {
if (nums[i] != prev) { // 如果遇到不同的数字
count++; // 增加不同数字的计数
if (count == 3) { // 如果达到第三个不同的数字
third_largest = nums[i]; // 记录第三大的数字
break; // 退出循环
}
prev = nums[i]; // 更新前一个不同的数字
}
}
// 如果整个数组中不同的数字少于三个,返回最大的数字
if (count < 3) {
return nums[0]; // 返回最大的数字
}
return third_largest; // 返回第三大的数字
}
int main() {
int nums[4] = {3, 2, 2, 1}; // 定义输入数组
printf("%d ", thirdMax(nums, 4)); // 调用函数并打印结果
return 0; // 程序结束,返回0
}
645. 错误的集合
集合 s
包含从 1
到 n
的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums
代表了集合 S
发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1:
输入:nums = [1,2,2,4]
输出:[2,3]
示例 2:
输入:nums = [1,1]
输出:[1,2]
cpp
#include <cstdio> // 包含标准输入输出头文件
#include <cstdlib>
#define N 9 // 定义数组大小为9
// 函数:找出数组中的最大值
int findMax(int* temp, int size) {
int max = temp[0]; // 假设数组至少有一个元素,初始最大值为数组的第一个元素
for (int i = 1; i < size; i++) { // 遍历数组
if (temp[i] > max) { // 如果当前元素大于max,更新max
max = temp[i];
}
}
return max; // 返回最大值
}
// 函数:找出重复出现的整数和丢失的整数,并返回结果数组
int* findErrorNums(int* nums, int numsSize, int* returnSize) {
*returnSize = 2; // 返回数组的大小为2,包含重复和丢失的整数
int max = findMax(nums, numsSize); // 找出数组中的最大值
int* ans = (int*) malloc(2 * sizeof(int)); // 动态分配返回数组的空间
int* temp = (int*) malloc((max + 2) * sizeof(int)); // 动态分配一个辅助数组,大小为max+2,确保覆盖所有可能的数字
// 初始化辅助数组为0,记录每个数字出现的次数
for (int i = 0; i < max + 2; ++i) {
temp[i] = 0;
}
// 统计每个数字在输入数组中的出现次数
for (int i = 0; i < numsSize; ++i) {
temp[nums[i]]++;
}
// 查找重复的整数和丢失的整数
for (int i = 0; i < max + 2; ++i) {
if (temp[i] > 1) { // 如果某个数字出现次数超过1,说明它重复了
ans[0] = i; // 记录重复的整数
// 查找丢失的整数
// 优先检查重复的数字后面的数字是否存在丢失
if (i == 1 && temp[i + 1] == 0) { // 特殊情况:如果重复的是1,检查2是否丢失
ans[1] = i + 1;
return ans; // 返回结果
}
for (int j = i; j > 0; --j) { // 从重复数字的位置向前查找丢失的数字
if (temp[j] == 0) { // 找到丢失的数字
ans[1] = j;
return ans; // 返回结果
}
}
for (int j = i; j < max + 2; j++) { // 如果向前没找到,再向后查找丢失的数字
if (temp[j] == 0) {
ans[1] = j;
return ans; // 返回结果
}
}
}
}
return ans; // 返回结果
}
// 主函数
int main() {
int nums[N] = {3, 5, 9, 4, 1, 2, 7, 8, 1}; // 定义输入数组
int returnSize;
int* ans = findErrorNums(nums, N, &returnSize); // 调用函数获取结果
// 打印结果
for (int i = 0; i < returnSize; ++i) {
printf("%d ", ans[i]);
}
return 0; // 程序结束,返回0
}
697. 数组的度
给定一个非空且只包含非负数的整数数组 nums
,数组的 度 的定义是指数组里任一元素出现频数的最大值。
你的任务是在 nums
中找到与 nums
拥有相同大小的度的最短连续子数组,返回其长度。
示例 1:
输入:nums = [1,2,2,3,1]
输出:2
解释:
输入数组的度是 2 ,因为元素 1 和 2 的出现频数最大,均为 2 。
连续子数组里面拥有相同度的有如下所示:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
最短连续子数组 [2, 2] 的长度为 2 ,所以返回 2 。
示例 2:
输入:nums = [1,2,2,3,1,4,2]
输出:6
解释:
数组的度是 3 ,因为元素 2 重复出现 3 次。
所以 [2,2,3,1,4,2] 是最短子数组,因此返回 6 。
提示:
nums.length
在1
到50,000
范围内。nums[i]
是一个在0
到49,999
范围内的整数
cpp
#include <stdio.h>
#include <stdlib.h>
// 功能:找出数组中的最大值
// 参数:nums - 数组,numsSize - 数组长度
// 返回值:数组中的最大值
int findMax(int* nums, int numsSize) {
int max = nums[0]; // 初始化最大值为数组的第一个元素
for (int i = 1; i < numsSize; i++) { // 遍历数组,寻找最大值
if (nums[i] > max) {
max = nums[i]; // 更新最大值
}
}
return max;
}
// 功能:找出数组中最短的同度子数组的长度
// 参数:nums - 数组,numsSize - 数组长度
// 返回值:最短同度子数组的长度
int findShortestSubArray(int* nums, int numsSize) {
if (numsSize == 0) return 0; // 如果数组为空,返回0
// 使用三个数组记录每个元素的出现次数、首次出现的位置和最后一次出现的位置。
int maxVal = findMax(nums, numsSize); // 获取数组中的最大值,用于确定数组的大小
int* count = (int*)malloc((maxVal + 1) * sizeof(int)); // 用于记录每个元素的出现次数
int* first = (int*)malloc((maxVal + 1) * sizeof(int)); // 用于记录每个元素首次出现的位置
int* last = (int*)malloc((maxVal + 1) * sizeof(int)); // 用于记录每个元素最后一次出现的位置
// 初始化三个数组
for (int i = 0; i <= maxVal; i++) {
count[i] = 0; // 初始出现次数为0
first[i] = -1; // 初始首次出现的位置为-1
last[i] = -1; // 初始最后一次出现的位置为-1
}
// 遍历数组,填充count、first和last数组
for (int i = 0; i < numsSize; i++) {
int num = nums[i]; // 当前元素
count[num]++; // 更新出现次数
if (first[num] == -1) { // 如果是第一次出现该元素
first[num] = i; // 记录首次出现的位置
}
last[num] = i; // 更新最后一次出现的位置
}
// 找出数组中的最大度数(最大出现次数)
int maxDegree = 0;
for (int i = 0; i <= maxVal; i++) {
if (count[i] > maxDegree) {
maxDegree = count[i]; // 更新最大度数
}
}
// 计算最短子数组长度
int minLen = numsSize; // 初始化最短长度为数组长度
for (int i = 0; i <= maxVal; i++) {
if (count[i] == maxDegree) { // 如果该元素的出现次数等于最大度数
int currentLen = last[i] - first[i] + 1; // 当前元素的子数组长度
if (currentLen < minLen) {
minLen = currentLen; // 更新最短长度
}
}
}
// 释放动态分配的内存
free(count);
free(first);
free(last);
return minLen;
}
int main() {
int nums[] = {1, 2, 2, 3, 1}; // 示例数组
int numsSize = sizeof(nums) / sizeof(nums[0]); // 数组长度
printf("最短子数组长度为: %d\n", findShortestSubArray(nums, numsSize)); // 测试并打印结果
return 0;
}
给你一个含 n
个整数的数组 nums
,其中 nums[i]
在区间 [1, n]
内。请你找出所有在 [1, n]
范围内但没有出现在 nums
中的数字,并以数组的形式返回结果。
示例 1:
输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]
示例 2:
输入:nums = [1,1]
输出:[2]
提示:
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
cpp
#include <cstdio>
#include <cstdlib>
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {
// 申请结果数组,大小为numsSize+1,用于存储消失的数字
int* ans = (int*) malloc((numsSize + 1) * sizeof(int));
// 申请辅助数组temp,大小为numsSize+1,用于计数每个数字出现的次数
int* temp = (int*) malloc((numsSize + 1) * sizeof(int));
// 初始化结果数组ans和辅助数组temp,将所有元素置为0
for (int i = 0; i < numsSize + 1; ++i) {
temp[i] = 0;
ans[i] = 0;
}
// 遍历输入数组nums,统计每个数字出现的次数
for (int i = 0; i < numsSize; ++i) {
int num = nums[i];
temp[num]++; // 将对应位置的计数加1
}
// 遍历辅助数组temp,找出计数为0的数字,即为消失的数字
int j = 0;
for (int i = 1; i < numsSize + 1; ++i) {
if (temp[i] == 0) {
ans[j++] = i; // 将消失的数字存入结果数组
}
}
// 设置返回的大小为消失的数字的数量
*returnSize = j;
return ans;
}
int main() {
int nums[] = {1,1};
int numsSize = sizeof(nums) / sizeof(nums[0]); // 数组长度
int returnSize = 0;
int* ans = findDisappearedNumbers(nums,numsSize,&returnSize);
for (int i = 0; i < returnSize; ++i) {
printf("%d ",ans[i]);
}
return 0;
}
283. 移动零
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
cpp
#include <cstdio> // 包含标准输入输出头文件
#include <cstdlib> // 包含标准库头文件
// 函数:将数组中的零元素移动到数组的末尾,同时保持非零元素的相对顺序
// 方法:类似冒泡排序,通过交换相邻元素将零元素向后移动
void moveZeroes(int* nums, int numsSize) {
// 外层循环控制遍历的次数
for (int i = numsSize - 1; i >= 0; i--) {
// 内层循环用于比较相邻元素并交换
for (int j = 0; j < i; ++j) {
if (nums[j] == 0) { // 如果当前元素是零
// 交换当前元素和下一个元素
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
// 打印结果数组
for (int i = 0; i < numsSize; ++i) {
printf("%d ", nums[i]);
}
}
int main() {
int nums[] = {0, 1, 0, 3, 12}; // 示例输入数组
int numsSize = sizeof(nums) / sizeof(nums[0]); // 计算数组长度
moveZeroes(nums, numsSize); // 调用函数处理数组
return 0; // 程序结束
}
cpp
#include <cstdio> // 包含标准输入输出头文件
#include <cstdlib> // 包含标准库头文件
// 功能:将数组中的零元素移动到数组的末尾,同时保持非零元素的相对顺序
// 参数:nums - 数组,numsSize - 数组长度
void moveZeroes(int* nums, int numsSize) {
int current = 0; // 当前数组的位置,用于记录非零元素的放置位置
// 遍历数组,将非零元素移动到数组的前面
for (int i = 0; i < numsSize; ++i) {
if (nums[i] != 0) { // 如果当前元素不是零
nums[current++] = nums[i]; // 将非零元素移动到 current 指定的位置,并递增 current
}
}
// 将数组中剩余的位置填充为零
for (int i = current; i < numsSize; ++i) {
nums[i] = 0; // 从 current 开始,将后续元素全部设置为零
}
// 打印处理后的数组
for (int i = 0; i < numsSize; ++i) {
printf("%d ", nums[i]); // 逐个打印数组元素
}
}
int main() {
int nums[] = {0, 1, 0, 3, 12}; // 定义示例输入数组
int numsSize = sizeof(nums) / sizeof(nums[0]); // 计算数组长度
moveZeroes(nums, numsSize); // 调用函数处理数组
return 0; // 程序结束
}