数组篇
- 26.删除有序数组中的重复项
- 27. 移除元素
- 35. 搜索插入位置
- 66. 加1
- 88. 合并两个有序数组
- 108. 将有序数组转换为二叉搜索树
- 118. 杨辉三角
- 119. 杨辉三角 II
- 136. 只出现一次的数字
- 169. 多数元素
- 217. 存在重复元素
- 219. 存在重复元素 II
- 228. 汇总区间
- 268.丢失的数字
- 283.移动零
- 349.两个数组的交集
- 350. 两个数组的交集 II
- 414. 第三大的数
- 448. 找到所有数组消失的数字
- 455. 分发饼干
- 496. 下一个更大元素 I
- 506. 相对名次
- 561. 数组拆分
- 575. 分糖果
- 605. 种花问题
- 628. 三个数的最大乘积
- 643. 子数组最大平均数 I
26.删除有序数组中的重复项
题目详情
给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
返回 k 。
题解
int removeDuplicates(int* nums, int numsSize) {
int i=0,count;
for(int j=1;j<numsSize;j++){
if(nums[i]!=nums[j])
nums[++i]=nums[j];
}
count=i+1; // i是数组下标,count应该比i多1.
return count;
}
27. 移除元素
##题目详情
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
题解
int removeElement(int* nums, int numsSize, int val) {
int count=0; // 记录val值的个数
for(int i=0;i<numsSize;i++){
if(nums[i]==val) // 数组的值等于val值,count++
count++;
else
nums[i-count]=nums[i];
}
return numsSize-count;
}
35. 搜索插入位置
题目详情
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
题解
int searchInsert(int* nums, int numsSize, int target) {
int low=0,high=numsSize-1;
while(low<=high){
int mid=(low+high)/2;
if(nums[mid]==target)
return mid;
else if(nums[mid]>target)
high=mid-1;
else
low=mid+1;
}
return low; // low指向的位置是target元素应该在数组中存放的位置
}
66. 加1
题目详情
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
题解
int* plusOne(int* digits, int digitsSize, int* returnSize) {
for(int i=digitsSize-1;i>=0;i--){
if(digits[i]<9){
digits[i]++;
(*returnSize)=digitsSize;
return digits;
}else{
digits[i]=0;
}
}
int* res=(int*)malloc(sizeof(int)*(digitsSize+1));
res[0]=1;
for(int i=1;i<digitsSize+1;i++)
res[i]=digits[i-1];
(*returnSize)=digitsSize+1;
return res;
}
88. 合并两个有序数组
题目详情
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
题解
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int i, j = 0, k = 0, tempNums1[nums1Size];
for (i = 0; i < m; i++) // 移动元素到tempNums1中
tempNums1[i] = nums1[i];
i = 0;
while (i < m && j < n) {
if (tempNums1[i] < nums2[j]) {
nums1[k++]=tempNums1[i++];
}else{
nums1[k++]=nums2[j++];
}
}
while(i<m){
nums1[k++]=tempNums1[i++];
}
while(j<n){
nums1[k++]=nums2[j++];
}
}
108. 将有序数组转换为二叉搜索树
题目详情
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
题解
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* travel(int nums[],int low,int high){
if(low>high) return NULL;
int mid=(low+high)/2;
struct TreeNode* root=(struct TreeNode*)malloc(sizeof(struct TreeNode));
root->val=nums[mid];
root->left=travel(nums,low,mid-1);
root->right=travel(nums,mid+1,high);
return root;
}
struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {
struct TreeNode* head=travel(nums,0,numsSize-1);
return head;
}
注意
// 第一种
struct TreeNode{
int data;
struct TreeNode* left;
struct TreeNode* right;
}TLnode;
// 第二种
struct TreeNode{
int data;
struct TreeNode* left;
struct TreeNode* right;
};
// 为第一种的话,函数的返回值可以写为 TLnode 或 struct TreeNode
// 为第一种的话,函数的返回值可以写为 struct TreeNode
118. 杨辉三角
题目详情
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
题解
int** generate(int numRows, int* returnSize, int** returnColumnSizes){
//返回的是二维数组,所以需要保存每一行的信息
*returnSize = numRows; // 返回有几列
*returnColumnSizes = (int *)malloc(sizeof(int)*numRows);//returnColumnSizes储存杨辉三角每一行元素的个数
int** res = (int**)malloc(sizeof(int*)*numRows);
for (int i = 0; i < numRows; i++) {
(*returnColumnSizes)[i] = i+1;
res[i] = (int*)malloc(sizeof(int)*(i+1));
res[i][0] = 1;
res[i][i] = 1;
for (int j = 1; j < i; j++) {
res[i][j] = res[i-1][j] + res[i-1][j-1];
}
}
return res;
}
119. 杨辉三角 II
题目详情
给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例 1:
输入: rowIndex = 3
输出: [1,3,3,1]
示例 2:
输入: rowIndex = 0
输出: [1]
示例 3:
输入: rowIndex = 1
输出: [1,1]
题解
int* getRow(int rowIndex, int* returnSize) {
*returnSize = (rowIndex + 1);
int** arr = (int**)malloc(sizeof(int*) * (rowIndex+1));
int i, j;
for (i = 0; i < rowIndex+1; i++) {
arr[i] = (int*)malloc(sizeof(int) * (i + 1));
arr[i][0] = 1;
arr[i][i] = 1;
for (j = 1; j < i; j++) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
}
return arr[rowIndex];
}
136. 只出现一次的数字
题目详情
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
示例 1 :
输入:nums = [2,2,1]
输出:1
示例 2 :
输入:nums = [4,1,2,1,2]
输出:4
示例 3 :
输入:nums = [1]
输出:1
题解
int singleNumber(int* nums, int numsSize) {
int res=0;
for(int i=0;i<numsSize;i++)
res^=nums[i];
return res;
}
169. 多数元素
题目详情
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3]
输出:3
示例 2:
输入:nums = [2,2,1,1,1,2,2]
输出:2
题解
int majorityElement(int* nums, int numsSize) {
int i, vote = 0,
elector; // vote 投票数 elector 选举者(把数组里面的数字看做选举者)
for (i = 0; i < numsSize; i++) {
if (!vote) {
elector = nums[i];
}
if (elector == nums[i])
vote++;
else
vote--;
}
return elector;
}
摩尔投票算法
该算法的核心就是对拼消耗
摩尔投票算法的优点
时间复杂度低:算法只需要遍历数组两次,时间复杂度为O(n),其中n是数组长度。
空间复杂度低:算法只需要常数级的额外空间,因此空间复杂度为O(1)。 ●
高效:适用于大规模数据,能够在较短时间内找到主要元素。
摩尔投票算法的缺点
- 不适用于所有情况:==算法要求主要元素的出现次数超过一半,因此对于没有主要元素的情况不适用。 ==
- 需要额外验证:算法找到候选主要元素后,还需要额外的遍历来验证其是否真的满足条件。
摩尔投票算法
217. 存在重复元素
题目详情
给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。
示例 1:
输入:nums = [1,2,3,1]
输出:true
示例 2:
输入:nums = [1,2,3,4]
输出:false
示例 3:
输入:nums = [1,1,1,3,3,4,3,2,4,2]
输出:true
题解
int cmpfunc(const void* a, const void* b) { return (*(int*)a - *(int*)b); }
bool containsDuplicate(int* nums, int numsSize) {
qsort(nums, numsSize, sizeof(int), cmpfunc);
for (int i = 0; i < numsSize-1; i++) {
if (nums[i] == nums[i+1])
return true;
}
return false;
}
219. 存在重复元素 II
题目详情
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [1,2,3,1], k = 3
输出:true
示例 2:
输入:nums = [1,0,1,1], k = 1
输出:true
示例 3:
输入:nums = [1,2,3,1,2,3], k = 2
输出:false
题解
typedef struct{
int data;
int index;
}record;
int cmp(int* a,int* b){
return (*(record*)a).data-(*(record*)b).data;
}
bool containsNearbyDuplicate(int* nums, int numsSize, int k) {
record temp[numsSize]; // 采用辅助数组
for(int i=0;i<numsSize;i++){
temp[i].data=nums[i];
temp[i].index=i;
}
qsort(temp,numsSize,sizeof(record),cmp);
for (int i = 0; i < numsSize-1; i++) {
if (temp[i].data == temp[i+1].data && abs(temp[i].index - temp[i+1].index) <= k)
return true;
}
return false;
}
228. 汇总区间
题目详情
给定一个 无重复元素 的 有序 整数数组 nums 。
返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。
列表中的每个区间范围 [a,b] 应该按如下格式输出:
“a->b” ,如果 a != b
“a” ,如果 a == b
示例 1:
输入:nums = [0,1,2,4,5,7]
输出:[“0->2”,“4->5”,“7”]
解释:区间范围是:
[0,2] --> “0->2”
[4,5] --> “4->5”
[7,7] --> “7”
示例 2:
输入:nums = [0,2,3,4,6,8,9]
输出:[“0”,“2->4”,“6”,“8->9”]
解释:区间范围是:
[0,0] --> “0”
[2,4] --> “2->4”
[6,6] --> “6”
[8,9] --> “8->9”
题解
char** summaryRanges(int* nums, int numsSize, int* returnSize) {
char** ret = malloc(sizeof(char*) * numsSize);
*returnSize = 0;
int i = 0;
while (i < numsSize) {
int low = i;
i++;
while (i < numsSize && nums[i] == nums[i - 1] + 1) {
i++;
}
int high = i - 1;
char* temp = malloc(sizeof(char) * 25);
sprintf(temp, "%d", nums[low]);
if (low < high) {
sprintf(temp + strlen(temp), "->");
sprintf(temp + strlen(temp), "%d", nums[high]);
}
ret[(*returnSize)++] = temp;
}
return ret;
}
268.丢失的数字
题目详情
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
示例 1:
输入:nums = [3,0,1]
输出:2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums 中。
示例 2:
输入:nums = [0,1]
输出:2
解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2 是丢失的数字,因为它没有出现在 nums 中。
示例 3:
输入:nums = [9,6,4,2,3,5,7,0,1]
输出:8
解释:n = 9,因为有 9 个数字,所以所有的数字都在范围 [0,9] 内。8 是丢失的数字,因为它没有出现在 nums 中。
示例 4:
输入:nums = [0]
输出:1
解释:n = 1,因为有 1 个数字,所以所有的数字都在范围 [0,1] 内。1 是丢失的数字,因为它没有出现在 nums 中。
题解
int cmp(const void* a, const void* b) { return *((int*)a) - *((int*)b); }
int missingNumber(int* nums, int numsSize) {
qsort(nums, numsSize, sizeof(int), cmp);
int i = 0;
if (nums[i] != 0)
return 0;
for (i = 1; i < numsSize; i++) {
if (nums[i - 1] + 1 != nums[i])
break;
}
return nums[i - 1] + 1;
}
283.移动零
题目详情
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
题解
void moveZeroes(int* nums, int numsSize) {
int i, k = 0, count = 0; // k负责记录0出现的次数
for (i = 0; i < numsSize; i++) {
if (nums[i] != 0)
nums[k++] = nums[i];
}
for (i = k; i < numsSize; i++)
nums[i] = 0;
}
349.两个数组的交集
题目详情
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的
题解
int cmp(const void* a,const void* b){
return (*(int*)a-*(int*)b);
}
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size,int* returnSize) {
int i,count=0,k=0,j=0, assist[1000] = {0};
int* arr = (int*)malloc(sizeof(int) * ((nums1Size > nums2Size) ? nums1Size : nums2Size));
for (i = 0; i < nums1Size; i++) // 存储nums1各数出现的次数
assist[nums1[i]]++;
for(i=0;i<nums2Size;i++){
if(assist[nums2[i]]>=1)
arr[k++]=nums2[i];
}
if(k==0){
*returnSize=0;
return arr;
}
qsort(arr,k,sizeof(int),cmp);
for(i=1;i<k;i++)
if(arr[i]!=arr[j])
arr[++j]=arr[i];
*returnSize=j+1;
return arr;
}
350. 两个数组的交集 II
题目详情
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
题解
int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; }
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size,
int* returnSize) {
int i = 0, j = 0, k = 0;
int* arr = malloc(sizeof(int) * (nums1Size > nums2Size ? nums1Size : nums2Size));
qsort(nums1, nums1Size, sizeof(int), cmp);
qsort(nums2, nums2Size, sizeof(int), cmp);
while (i < nums1Size && j < nums2Size) {
if (nums1[i] == nums2[j]) {
arr[k++] = nums1[i];
i++;
j++;
} else if (nums1[i] < nums2[j])
i++;
else
j++;
}
*returnSize = k;
return arr;
}
414. 第三大的数
题目详情
给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。
示例 1:
输入:[3, 2, 1]
输出:1
解释:第三大的数是 1 。
示例 2:
输入:[1, 2]
输出:2
解释:第三大的数不存在, 所以返回最大的数 2 。
示例 3:
输入:[2, 2, 3, 1]
输出:1
解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。
此例中存在两个值为 2 的数,它们都排第二。在所有不同数字中排第三大的数为 1 。
题解
int thirdMax(int* nums, int numsSize) {
int i;
long max[3] = {LONG_MIN, LONG_MIN, LONG_MIN};
for (i = 0; i < numsSize; i++) {
if (nums[i] > max[0]) {
max[2] = max[1];
max[1] = max[0];
max[0] = nums[i];
} else if (nums[i] < max[0] && nums[i] > max[1]) {
max[2] = max[1];
max[1] = nums[i];
} else if (nums[i] < max[1] && nums[i] > max[2]) {
max[2] = nums[i];
}
}
if (max[2] == LONG_MIN)
return max[0];
else
return max[2];
}
448. 找到所有数组消失的数字
题目详情
给你一个含 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]
题解
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {
int i = 0,k=0;
int* arr = malloc(sizeof(int) * (numsSize+1));
int *ret=malloc(sizeof(int)*numsSize);
for (i = 1; i <= numsSize; i++)
arr[i] = 0;
// 出现的位置1
for (i = 0; i < numsSize; i++)
arr[nums[i]] = 1;
for(i=1;i<=numsSize;i++)
if(arr[i]==0)
ret[k++]=i;
*returnSize=k;
return ret;
}
455. 分发饼干
题目详情
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
示例 1:
输入: g = [1,2,3], s = [1,1]
输出: 1
解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。
示例 2:
输入: g = [1,2], s = [1,2,3]
输出: 2
解释:
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.
题解
int cmp(const void* a, const void* b) { return (*(int*)a - *(int*)b); }
int findContentChildren(int* g, int gSize, int* s, int sSize) {
int i = 0, j = 0, count = 0;
// 进行排序
qsort(g, gSize, sizeof(int), cmp);
qsort(s, sSize, sizeof(int), cmp);
while (i < sSize && j < gSize) {
// 饼干如果大于孩子的胃口 i++; j++; s是饼干 g是孩子的胃口
if (s[i] >= g[j]) {
i++;
j++;
count++;
} else
i++;
}
return count;
}
496. 下一个更大元素 I
nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。
给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。
对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。
返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。
示例 1:
输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
示例 2:
输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。
题解
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size,
int* returnSize) {
*returnSize = nums1Size;
int k = 0, m;
int* arr = malloc(sizeof(int) * nums1Size);
for (int i = 0; i < nums1Size; i++) {
int j = 0;
while (j < nums2Size && nums1[i] != nums2[j])
j++;
int k = j + 1;
while (k < nums2Size && nums2[k] < nums2[j])
k++;
arr[i] = k < nums2Size ? nums2[k] : -1;
}
return arr;
}
506. 相对名次
题目详情
给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。
运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:
名次第 1 的运动员获金牌 “Gold Medal” 。
名次第 2 的运动员获银牌 “Silver Medal” 。
名次第 3 的运动员获铜牌 “Bronze Medal” 。
从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 “x”)。
使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。
示例 1:
输入:score = [5,4,3,2,1]
输出:[“Gold Medal”,“Silver Medal”,“Bronze Medal”,“4”,“5”]
解释:名次为 [1st, 2nd, 3rd, 4th, 5th] 。
示例 2:
输入:score = [10,3,8,9,4]
输出:[“Gold Medal”,“5”,“Bronze Medal”,“Silver Medal”,“4”]
解释:名次为 [1st, 5th, 3rd, 2nd, 4th] 。
题解
typedef struct record {
int data;
int index;
} record;
int cmp(const void* a, const void* b) {
return (*(record*)b).data - (*(record*)a).data;
}
char** findRelativeRanks(int* score, int scoreSize, int* returnSize) {
// 申请动态二维数组
char** arr = malloc(sizeof(char*) * scoreSize);
record recordRanks[scoreSize];
for (int i = 0; i < scoreSize; i++) {
recordRanks[i].data = score[i];
recordRanks[i].index = i;
}
qsort(recordRanks, scoreSize, sizeof(record), cmp);
for (int i = 0; i < scoreSize; i++) {
char* temp = malloc(sizeof(char) * 25);
if (i == 0) // 第一名
sprintf(temp, "%s", "Gold Medal");
else if (i == 1)
sprintf(temp, "%s", "Silver Medal");
else if (i == 2)
sprintf(temp, "%s", "Bronze Medal");
else
sprintf(temp, "%d", i + 1);
arr[recordRanks[i].index] = temp;
}
*returnSize = scoreSize;
return arr;
}
561. 数组拆分
题目详情
给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
返回该 最大总和 。
示例 1:
输入:nums = [1,4,3,2]
输出:4
解释:所有可能的分法(忽略元素顺序)为:
- (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3
- (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3
- (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4
所以最大总和为 4
示例 2:
输入:nums = [6,2,6,5,1,2]
输出:9
解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9
题解
int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; }
int arrayPairSum(int* nums, int numsSize) {
int min, ret = 0;
qsort(nums, numsSize, sizeof(int), cmp);
for (int i = 0; i < numsSize; i++) { // 遍历找到每两个的最小值
if (i % 2 == 0)
min = nums[i];
else {
min = min < nums[i] ? min : nums[i];
ret += min;
}
}
return ret;
}
575. 分糖果
题目详情
Alice 有 n 枚糖,其中第 i 枚糖的类型为 candyType[i] 。Alice 注意到她的体重正在增长,所以前去拜访了一位医生。
医生建议 Alice 要少摄入糖分,只吃掉她所有糖的 n / 2 即可(n 是一个偶数)。Alice 非常喜欢这些糖,她想要在遵循医生建议的情况下,尽可能吃到最多不同种类的糖。
给你一个长度为 n 的整数数组 candyType ,返回: Alice 在仅吃掉 n / 2 枚糖的情况下,可以吃到糖的 最多 种类数。
示例 1:
输入:candyType = [1,1,2,2,3,3]
输出:3
解释:Alice 只能吃 6 / 2 = 3 枚糖,由于只有 3 种糖,她可以每种吃一枚。
示例 2:
输入:candyType = [1,1,2,3]
输出:2
解释:Alice 只能吃 4 / 2 = 2 枚糖,不管她选择吃的种类是 [1,2]、[1,3] 还是 [2,3],她只能吃到两种不同类的糖。
示例 3:
输入:candyType = [6,6,6,6]
输出:1
解释:Alice 只能吃 4 / 2 = 2 枚糖,尽管她能吃 2 枚,但只能吃到 1 种糖。
题解
int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; }
int distributeCandies(int* candyType, int candyTypeSize) {
qsort(candyType, candyTypeSize, sizeof(int), cmp);
int i, k = 0, sum = 0, count = 0;
for (i = 0; i < candyTypeSize; i++)
if (candyType[k] != candyType[i])
candyType[++k] = candyType[i];
if(k+1>candyTypeSize/2)
return candyTypeSize/2;
else
return k+1;
}
605. 种花问题
题目详情
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false 。
示例 1:
输入:flowerbed = [1,0,0,0,1], n = 1
输出:true
示例 2:
输入:flowerbed = [1,0,0,0,1], n = 2
输出:false
题解
bool canPlaceFlowers(int* flowerbed, int flowerbedSize, int n) {
int i = 0, count = n;
if (n == 0)
return true;
for (i = 0; i < flowerbedSize; i++) {
int pre = i > 0 ? flowerbed[i - 1] : 0;
int cur = flowerbed[i];
int next = i < flowerbedSize - 1 ? flowerbed[i + 1] : 0;
if (pre == 0 && cur == 0 && next == 0) {
flowerbed[i] = 1;
count--;
}
if (count == 0)
return true;
}
return false;
}
628. 三个数的最大乘积
题目详情
给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
示例 1:
输入:nums = [1,2,3]
输出:6
示例 2:
输入:nums = [1,2,3,4]
输出:24
示例 3:
输入:nums = [-1,-2,-3]
输出:-6
题解
int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; }
int maximumProduct(int* nums, int numsSize) {
int maximum = INT_MIN;
qsort(nums, numsSize, sizeof(int), cmp); // 进行排序
maximum = nums[numsSize - 1] * nums[numsSize - 2] * nums[numsSize - 3];
maximum = maximum > nums[0] * nums[1] * nums[numsSize - 1]? maximum: nums[0] * nums[1] * nums[numsSize - 1];
return maximum;
}
643. 子数组最大平均数 I
题目详情
给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。
请你找出平均数最大且 长度为 k 的连续子数组,并输出该最大平均数。
任何误差小于 10-5 的答案都将被视为正确答案。
示例 1:
输入:nums = [1,12,-5,-6,50,3], k = 4
输出:12.75
解释:最大平均数 (12-5-6+50)/4 = 51/4 = 12.75
示例 2:
输入:nums = [5], k = 1
输出:5.00000
题解
double findMaxAverage(int* nums, int numsSize, int k) {
int i, start, end;
double sum = 0, res;
// 计算前k个数字之和
for (i = 0; i < k; i++)
sum += nums[i];
res = sum;
for (start = 0, end = k; end < numsSize; end++, start++) {
sum += nums[end] - nums[start];
res = sum > res ? sum : res;
}
return res / k;
}