leecode算法题之数组

目录

1.合并正序数组并求中位数

1.题目剖析

2.代码示例

3.拓展思考

2.盛最多水的容器

1.题目剖析

2.代码示例

3.运行结果

4.算法改进

5.改进代码示例


今天也没学什么新东西,那就给大家上两道力扣算法题叭。

1.合并正序数组并求中位数

leecode算法题之数组_第1张图片

这道题在之前的帖子中(指针第四卷)也提到过,但没有详细去讲,今天就详细讲一下这道题。

1.题目剖析

首先看这道题的题目,给定两个正序数组,并求出它们的中位数,再根据下方输入输出提示,我们首先想到的就是合并数组,遍历这两个正序数组,并把其中的元素存放到另一个空数组记作nums3中。这里我们需要注意的一点是在遍历完nums1,并且将nums1中的元素存放进nums3中后,我们开始遍历nums2,但这时存放元素的时候nums3和nums2的下标并不一致,切应该相差nums1Size,相当于是把nums2中的元素接轨到nums1元素的后面。

合并完数组后注意此时nums3中的元素是乱序的,所以我们要对nums3进行排序,这里我用到了C语言标准库函数qsort函数排序,它的底层原理采用快速排序,效率高。

对nums3排完序后就可以去找中位数,注意要分奇数列和偶数列两种情况。

2.代码示例

#include 
#include 
int cmp_nums3(const void* p1, const void* p2)
{
    return *((int*)p1) - *((int*)p2);
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size)
{
    int nums3[nums1Size + nums2Size];
    for(int i=0; i < nums1Size; i++)
            nums3[i] = nums1[i];
    for(int j=0; j < nums2Size; j++)
            nums3[nums1Size + j] = nums2[j];
    qsort(nums3, nums1Size + nums2Size, sizeof(int), cmp_nums3);
    if((nums1Size + nums2Size) % 2 == 0)
            return (double)(nums3[(nums1Size + nums2Size) / 2 - 1] + nums3[(nums1Size + nums2Size) / 2]) / 2;
    else
            return (double)nums3[(nums1Size + nums2Size) / 2];
}

3.拓展思考

对于这道题来说以上只是常规解法,并没有用到算法(除了qsort函数自带的快速排序用到了分治),那我们还有没有其他更巧妙简洁的方法,比如既然nums1和nums2都是正序数组,是否可以采用插入排序思想,把nums2中的元素插入到nums1中呢?

2.盛最多水的容器

leecode算法题之数组_第2张图片

leecode算法题之数组_第3张图片

1.题目剖析

首先分析题目的意思简单来说就是求该柱形图的最大面积(要满足木桶原理)

那我们可以采用最暴力的方法把所有面积求出来,然后引入max变量找最大值,并进行动态更新

2.代码示例

int maxArea(int* height, int heightSize)
{
    int max = 0, arr[100];
    for (int j = 0; j <= heightSize - 2; j++)
    {
         for (int i = j + 1; i <= heightSize - 1; i++)
         {
              if (height[j] > height[i])
                  arr[j] = height[i] * (i - j);
              else arr[j] = height[j] * (i - j);
              if (max < arr[j])
                  max = arr[j];
         }
    }
    return max;
}

3.运行结果

leecode算法题之数组_第4张图片

但是力扣身为一个练习算法的平台,一定不会让你这么简单就通过,果不其然,他的最后几组测试用例的长度都是以万为单位的,这样的话你用嵌套for循环至少要循环上百万次,肯定超时。

4.算法改进

我们再来仔细分析一下题目,就用题目给的图去看

leecode算法题之数组_第5张图片

假设取左右两边(下标记作0和8)的两条线,那么这个面积记为S,接下来再取0和7,你会发现所构成矩形面积的长在缩小,而宽不变,那么面积一定比S小,那有的人该问了,如果款变量呢,根据木桶原理如果宽变,那也是出现了一个比0的高度还小的宽才导致宽变了,所以我们没必要挨个求每种情况的面积,只需要设置左右两个指针left和right,从两边开始求面积,求完后,如果左边的高度小,就让左指针左移,否则让右指针右移 ,因为两指针移动必然会导致矩形长度变小,那么想让矩形面积变大只能从高度上做文章,然后在定义一个变量max实时更新就行。

5.改进代码示例

int min(int x, int y)
{
    if (x > y)
        return y;
    else return x;
}
int maxArea(int* height, int heightSize)
{
    int left = 0, right = heightSize - 1, max = 0;//计算柱形图面积最大值(双指针)
    while (left < right)
    {
        int area = (right - left) * min(height[left], height[right]);
        if (area > max)
            max = area;
        if (height[right] < height[left])
            right--;
        else left++;
    }
    return max;
}

你可能感兴趣的:(算法)