LeetCode刷题笔记【数组】

《考研向》leetcode数据结构与程序设计刷题(数组篇,含思路解答)

485最大连续1的个数

在这里插入图片描述

算法思想:
1.设置两个变量max,curmax。其中max代表最大连续1的个数,curmax代表当前最大连续1的个数。
2.遍历数组,如果当前变量为1,则curmax++,并且比较当前curmax和max的大小,如果curmax更大则替换。
3.如果当前变量为0,则把curmax置为0。
int findMaxConsecutiveOnes(int* nums, int numsSize){
     int max=0,curmax=0;
     for(int i=0;i<numsSize;i++)
     {
         if(nums[i]==1)
         {
            curmax++;
             if(curmax>max)
                 max=curmax;
         }
         if(nums[i]==0)
            curmax=0;             
         }
     return max;
}

495 提莫攻击

在这里插入图片描述

动态转移方程为 sum += min(nums[i] - nums[i - 1], duration)
1.设置变量sum用来存储输出的数据。
2.遍历数组
如果前后两个元素之差小于duration,则sum+两元素之差;如果前后两个元素之差大于duration,则sum+duration。

int findPoisonedDuration(int* timeSeries, int timeSeriesSize, int duration){
        int sum=0;
        for(int i=1;i<timeSeriesSize;i++)
        {
            if(timeSeries[i]-timeSeries[i-1]>duration)
            sum+=duration;
            else
            sum+=timeSeries[i]-timeSeries[i-1];
        }
        sum+=duration;
        return sum;
}

414 第三大的数

在这里插入图片描述

1.设置一个数组max[3],用来存放数组中前三大的数。这里注意C语言数组赋值
/// int max[3]={333} max[0]=333,max[1]=0,max[2]=0;
/// 该方法仅可将数组元素初始化为0,若初始化为其他数字,仅有首元素可被初始化为该数字,其余元素自动初始化为0。
2.遍历数组,并且比较值,根据不同的大小依次修改数组max
3.最后返回max[3],若不存在则返回max[0]

int thirdMax(int* nums, int numsSize){
    long int max[3]={-1e10,-1e10,-1e10};
    for(int i=0;i<numsSize;i++)
    {
        printf("%d %d %d\n",max[0],max[1],max[2]);
        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]!=-1e10)
        return max[2];
    return max[0];
}

628 三个数的最大乘积

在这里插入图片描述

冒泡排序会超时,无语。
1.三个数的最大乘积有两种情况(1)三个最大的数相乘(2)最大的数和最小的两个数相乘
方法1:先对数组进行排序,选出这五个数
方法2:借鉴【414】,找到相应的数字

//方法一
int maximumProduct(int* nums, int numsSize){
    long int max[3]={-1e10,-1e10,-1e10};
    long int min[2]={1e10,1e10};
    for(int 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(nums[i]<min[1])
        {
            min[0]=min[1];
            min[1]=nums[i];
        }else if(nums[i]>=min[1]&&nums[i]<min[0])
        {
            min[0]=nums[i];
        }
    }
    int max1,max2;
    max1=max[0]*max[1]*max[2];
    max2=max[0]*min[0]*min[1];
    if(max1>max2)
    return max1;
    else
    return max2;
}
//方法二
int cmp(const void *a,const void *b)
{
    return (*(int*)a-*(int*)b);
}

int maximumProduct(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),cmp);
    int max1=nums[0]*nums[1]*nums[numsSize-1];
    int max2=nums[numsSize-3]*nums[numsSize-2]*nums[numsSize-1];
    if(max1>max2)
    return max1;
    else
    return max2;
}

C语言函数qsort()

	功能: 使用**快速排序**例程进行排序
	头文件:stdlib.h
  用法:  void qsort(void* base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*)); 
  参数: 1 待排序数组,排序之后的结果仍放在这个数组中
      2 数组中待排序元素数量
      3 各元素的占用空间大小(单位为字节)
      4 指向函数的指针,用于确定排序的顺序(需要用户自定义一个比较函数)
#include <stdio.h>
#include <stdlib.h>

int values[] = { 88, 56, 100, 2, 25 };

int cmpfunc (const void * a, const void * b)
{
   return ( *(int*)a - *(int*)b );
}
int main()
{
   int n;
   printf("排序之前的列表:\n");
   for( n = 0 ; n < 5; n++ ) {
      printf("%d ", values[n]);
   }
   printf("\n");
   qsort(values, 5, sizeof(int), cmpfunc);

   printf("\n排序之后的列表:\n");
   for( n = 0 ; n < 5; n++ ) {
      printf("%d ", values[n]);
   }
  return(0);
}

645 错误的集合

在这里插入图片描述

通过使用哈希表来和每个元素相对应。
1.初始化哈希表,值都设为false
2.遍历数组,出现则将对应的位置改为true,如果已经为true,则它就是重复的数字。
3.遍历哈希表,如果当年对应的值为false,则它就是丢失的整数。

int* findErrorNums(int* nums, int numsSize, int* returnSize){
    bool hash[numsSize+1];
    static int result[2];
    *returnSize=2;
    for(int i=0;i<numsSize+1;i++)
    {
        hash[i]=false;
    }
    for(int i=0;i<numsSize;i++)
    {
        int m=nums[i];
        if(hash[m]==false)
        hash[m]=true;
        else if(hash[m]==true)
        result[0]=nums[i];
    }
    for(int i=1;i<numsSize+1;i++)
    {
        if(hash[i]==false)
        {
            result[1]=i;
            break;
        }
    }
    return result;
}

697 数组的度

在这里插入图片描述

(感觉有点麻烦)
思路:找数组中的众数,并且众数不止一个
1.创建一个数组result,用于存储每个数的频度
2.遍历result数组找到频度最大的数(众数的频度)
3.遍历原数组(nums)包含众数的最小长度,如果众数不是一个,则需要对最小长度进行比较

int findShortestSubArray(int* nums, int numsSize){
        int result[100000]={0};
        for(int i=0;i<numsSize;i++)
            result[nums[i]]++;
        int fre=0;
        for(int i=0;i<100000;i++)
        {
            if(result[i]>fre)
                fre=result[i]; //找到找众数的频度
        }
        int com=100000,start,end,num;
        for(int i=0;i<100000;i++)
        {
            start=0,end=0,num=0;
            if(result[i]==fre)
                {
                num=i;
                for(int i=0;i<numsSize;i++)
                    {
                        if(nums[i]==num)
                            { 
                                start=i;
                                break;
                            }
                    }
                for(int i=numsSize-1;i>0;i--)
                    {
                        if(nums[i]==num)
                            {
                                end=i;
                                 break;
                            }
                    }
                if(end-start+1<com)
                    com=end-start+1;
                }
    }
        return com;
}

448找到所有数组中消失的数字

在这里插入图片描述

方法一:采用哈希表
1.建立长度为numsSize+1的哈希表并将初值设为false。
2.遍历数组,将hash[nums[i]设为ture。
3.再次遍历哈希表,将值为false的下标存入result数组,并记录数组长度。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){
    bool hash[numsSize+1];
    for(int i=0;i<numsSize+1;i++)
    hash[i]=false;
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]>=1&&nums[i]<=numsSize)
        hash[nums[i]]=true;
    }
    static int result[1000000]={0};
    int num=0;
    for(int i=1;i<numsSize+1;i++)
    {
        if(hash[i]==false)
        {
            result[num]=i;
            num++;
        }
    }
    *returnSize=num;
    return result;
}

方法二:
1.遍历数组,如果当前值在[1,n],就把其对应下标的数改成负数。
2.再次遍历数组,如果当前的值为正数,则说明这个数没有在数组中出现,返回i+1(其中i为下标)

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){
    int *array=(int *)malloc(sizeof(int)*numsSize);
    int num=0;
    for(int i=0;i<numsSize;i++)
    {
        //if(abs(nums[i])>=1&&abs(nums[i])<=numsSize)
        nums[abs(nums[i])-1]=-abs(nums[abs(nums[i])-1]);
    }
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]>0)
        {
            array[num++]=i+1;
        }
    }
    *returnSize=num;
    return array;
}

442 数组中重复的数据

在这里插入图片描述

方法一:设置哈希表,用于记录元素是否出现
1.遍历数组,将其对应的哈希表中的元素设置为true。
2.如果当前哈希表对应的值已经为true,则该整数出现两次,存入要返回的数组中。

int* findDuplicates(int* nums, int numsSize, int* returnSize){
    bool result[numsSize+1];
    for(int i=0;i<numsSize+1;i++)
    result[i]=false;
    int *array=(int *)malloc(sizeof(int)*numsSize);
    for(int i=0;i<numsSize;i++)
    array[i]=0;
    int w=0;
    for(int i=0;i<numsSize;i++)
    {
        if(result[nums[i]]==true)
        {
            array[w]=nums[i];
            w++;
        }else
        result[nums[i]]=true;
    }
    *returnSize=w;
    return array;
}

方法二:
1.建立数组array用于存储每个数的频度,数组result用于存储最后的结果并返回。
2.遍历数组nums,更新数组array。
3.遍历array,筛选频度为2的数字,存入result。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findDuplicates(int* nums, int numsSize, int* returnSize){
    int *array=(int *)malloc(sizeof(int)*(numsSize+1));
    int *result=(int *)malloc(sizeof(int)*(numsSize));
    int num=0;
    for(int i=0;i<numsSize+1;i++)
     array[i]=0;
    for(int i=0;i<numsSize;i++)
    {
        array[nums[i]]++;
    }
    for(int i=0;i<numsSize+1;i++)
    {
        printf("%d ",array[i]);
    }
    for(int i=0;i<numsSize+1;i++)
    {
        if(array[i]==2)
        result[num++]=i;
    }
    *returnSize=num;
    return result;
}

41 缺失的第一个正数

在这里插入图片描述

1.首先处理小于或等于0的数,将他们变为numsSize+1
2.遍历数组,将每个元素对应的下标减一,再找到对应的元素之后将其变为负数。
3.遍历数组,如果当前元素大于0,则下标+1就是缺失的正数,否则就是numsSize+1。

int firstMissingPositive(int* nums, int numsSize){
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]<=0)
        nums[i]=numsSize+1;
    }
    for(int i=0;i<numsSize;i++)
    {   
        if(abs(nums[i])<=numsSize
        nums[abs(nums[i])-1]=-abs(nums[abs(nums[i])-1]);
    }
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]>0)
        return i+1;
    }
    return numsSize+1;
}

// 3 4 -1 1
// 3 4 5 1
// 3 4 -5 1
// 3 4 -5 -1
// -3 4 -5 -1
所以缺失的第一个正数是2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值