文章目录
一.概念定义
两个数的最小值
两个数的最小值可以用if语句判断,也可以用C语言的三元运算符。
//if语句判断
int max(int a, int b){
if(a < b)
return b;
return a;
}
//三元运算符
int max(int a, int b){
return a > b ? a : b;//a > b ? 意思是a 是否大于b
//a : b表示如果前面条件成立就返回a,否则返回b
}
n个数的最小值
当有n个数时,我们可以先比较出俩个数的最大值,然后再用这个值与第三个值进行比较,一次类推,得出n个数的最大值。
int max(int* nums, int numsSize){
int max = INT_MIN;
for(int i = 0; i < numsSize; i++){
if(max < nums[i]){
max = nums[i];
}
}
return max;
}
课后习题
485. 最大连续 1 的个数
485. 最大连续 1 的个数
分析:
这道题时让我们统计一个数组中1的连续最长个数,并且用0来做间隔,这时我们则需要两个变量,max和cout,max用来记录最长连续个数,cout用来计算每个0间隔前的1的连续个数,每当读取到0时,对cout和max进行比较。
代码如下:
int findMaxConsecutiveOnes(int* nums, int numsSize){
int max = 0;
int cout = 0;
for(int i = 0; i < numsSize; i++){
if(nums[i] == 1){
cout++;
}
if(nums[i] == 0){
cout = 0;
}
if(max < cout){
max = cout;
}
}
return max;
}
1464. 数组中两元素的最大乘积
1464. 数组中两元素的最大乘积
因为nums[i]的区间为[1,1000],所以我们只需找出最大的两个值即可,因为数据量很小,所以我们可以直接遍历两遍,第一遍找出最大值,并记录下该数的下表,第二遍遍历就能找出第二大的值。
代码如下:
int maxProduct(int* nums, int numsSize){
int max1 = 0, x1;
int max2 = 0;
for(int i = 0; i < numsSize; i++){
if(max1 < nums[i]){
max1 = nums[i];
x1 = i;
}
}
for(int i = 0; i < numsSize; i++){
if(max2 < nums[i] && i != x1){
max2 = nums[i];
}
}
return (max1 - 1) * (max2 - 1);
}
153. 寻找旋转排序数组中的最小值
153. 寻找旋转排序数组中的最小值
这道题的有两种解法:
第一种:简单暴力,直接遍历
int findMin(int* nums, int numsSize){
int min = INT_MAX;
for(int i = 0; i < numsSize; i++){
if(min > nums[i]){
min = nums[i];
}
}
return min;
}
第二种:利用二分查找
因为所给定的数组nums是由一个递增序列经过1至n次的向右移动得到的,并且nums不存在相同的数,我们假设最小值为x,除去原来的递增情况,x左边的数必然大于x右边的数。
如图:
这时我们可以设定两个指针,分别指向最低位下标和最高位下标,再定义一个mid来存放中间下标,通过结合上面的分析我们可以发现会出现两种情况:
第一种:当numd[mid] > nums[high]时,假设最小值下标为x,mid是[mid,x) 这个区间内的最小值,这时我们可以除去左半部分。
第二种情况:当nums[mid] < nums[high]时,说明最小值再mid的左边,我们可以舍去右半部分。
代码如下:
int findMin(int* nums, int numsSize){
int low = 0;
int hight = numsSize - 1;
while(low < hight){
int mid = (low + hight) / 2;
if(nums[mid] < nums[hight]){
hight = mid;
}
else{
low = mid + 1;
}
}
return nums[low];
}
154. 寻找旋转排序数组中的最小值 II
154. 寻找旋转排序数组中的最小值 II
这道题与上面那道的区别是有相同的数据了,所以需要考虑一些特殊的情况,例如[1,3,3],[3,3,1,3]
前面两种情况和上题一样,新增的第三种情况是:nums[mid] == nums[high]
这种情况下,最小值一定是在high的左边,所以我们只需high-1即可。
代码如下:
int findMin(int* nums, int numsSize){
int low = 0;
int hight = numsSize - 1;
while(low < hight){
int mid = (low + hight) / 2;
if(nums[mid] < nums[hight]){
hight = mid;
}
else if(nums[mid] > nums[hight]){
low = mid + 1;
}
else{
hight--;
}
}
return nums[low];
}
414. 第三大的数
414. 第三大的数
这道题有两种解法:
方法一:排序
太过简单就不分析了"( ̄▽ ̄)"
代码:
int thirdMax(int* nums, int numsSize){
for(int i = 0; i < numsSize; i++){
for(int j = 0; j < numsSize - 1 - i; j++){
if(nums[j] < nums[j + 1]){
int tmp = nums[j + 1];
nums[j + 1] = nums[j];
nums[j] = tmp;
}
}
}
for (int i = 1, diff = 1; i < numsSize; ++i) {
if (nums[i] != nums[i - 1] && ++diff == 3) {
// 此时 nums[i] 就是第三大的数
return nums[i];
}
}
return nums[0];
}
方法二:一次遍历
我们可以设置三个变量max1,max2,max3分别存储前三个的最大值,由于数据范围在整型的最大边界,所以这三个变量的初始条件为LONG_MIN。
代码如下:
int thirdMax(int* nums, int numsSize){
long max[3];
max[0] = LONG_MIN;
max[1] = LONG_MIN;
max[2] = LONG_MIN;
for(int i = 0; i < numsSize; i++){
//先将最大的值给max[0]
if(max[0] < nums[i]){
max[2] = max[1];
max[1] = max[0];
max[0] = nums[i];
}
else if(max[0] > nums[i] && max[1] < nums[i]){
max[2] = max[1];
max[1] = nums[i];
}
else if(max[1] > nums[i] && max[2] < nums[i]){
max[2] = nums[i];
}
}
if(max[2] == LONG_MIN)
return max[0];
return max[2];
}
628. 三个数的最大乘积
628. 三个数的最大乘积
这道题也有两种解题方式
方法一:排序
由于nums[i]的取值范围在[-1000,1000],所以会有两种情况,最大的三个数相乘为最大值,或者最大的数与最小的两个数相乘为最大值。
代码如下:
int* cmp(const int* x1, const int* x2){
return *x1 - *x2;
}
int maximumProduct(int* nums, int numsSize){
qsort(nums, numsSize, sizeof(int), cmp);
return fmax(nums[0] * nums[1] * nums[numsSize - 1], nums[numsSize - 3] * nums[numsSize - 2] * nums[numsSize - 1]);
}
方法二:线性扫描
线性扫描我们需找出最大的三个数和最小的两个数。
代码如下:
int maximumProduct(int* nums, int numsSize){
int max[3];
max[0] = INT_MIN;
max[1] = INT_MIN;
max[2] = INT_MIN;
int min1 = INT_MAX;
int min2 = INT_MAX;
for(int i = 0; i < numsSize; i++){
if(max[0] < nums[i]){
max[2] = max[1];
max[1] = max[0];
max[0] = nums[i];
}
else if(max[1] < nums[i]){
max[2] = max[1];
max[1] = nums[i];
}
else if(max[2] < nums[i]){
max[2] = nums[i];
}
if(min1 > nums[i]){
min2 = min1;
min1 = nums[i];
}
else if(min2 > nums[i]){
min2 = nums[i];
}
}
return fmax(max[0] * max[1] * max[2], min1 * min2 * max[0]);
}