刷题02 数组easy

1752.数组是否能经排序和轮转得到

        如果整个数组非递减,返回true,如果只有两个子数列非递减,并且两个子序列之间是有序的,返回true。

        先找到第一个不满足非递减的位置i,如果i==numsize,说明整个数组非递减。否则,就判断另一个子数组是否是非递减的,若不是,返回false,若是,则判断两个子数组之间是否有序,只需要判断nums[0]与nums[numsize-1]的大小。nums[0]是第一个子数组的最小值,nums[numsize-1]是第二个子数组的最大值。

bool check(int* nums, int numsSize) {
    //需要满足数组是非递减的,或者有两个子序列非递减,且两个子序列是有序的
    int i,j;
    for(i=1;inums[i]){
            break;
        }
    }
    if(i==numsSize){//数组非递减
        return true;
    }
    for(int j=i+1;jnums[j]){
            return false;
        }
    }
    if(nums[0]>=nums[numsSize-1]){//判断两个子数组是否有序,
        return true;
    }
    return false;
}

1800.最大升序子数组和

        模拟,一次遍历。用cur记录当前最大子数组和,升序cur就加nums[i],破坏了升序就让cur=nums[i]

int maxAscendingSum(int* nums, int numsSize) {
    //模拟
    int ans=0,cur=0;
    for(int i=0;ians) ans=cur;
        }else{
            cur=nums[i];
        }
    }
    return ans;
}

 1827.最少操作使数组递增

        一次遍历,如果nums[i-1]>=nums[i],就更新nums[i]。采用贪心的思想,遍历数组进行判断当前局部是否满足递增,不满足就进行操作使其递增。

int minOperations(int* nums, int numsSize){
    int ans=0;
    for(int i=1;i=nums[i]){
            ans+=nums[i-1]+1-nums[i];
            nums[i]=nums[i-1]+1;
        }
    }
    return ans;
}

 1909.删除一个元素使数组有序

        该题可以住转化为找数组中是否有且仅有一个驼峰或者低谷元素,这里需要注意是三个元素都有严格的大小,只要有一个不满足就不行。

bool canBeIncreasing(int* nums, int numsSize) {
    if(numsSize<=2) return true;
    bool flag=true;//判断是否找到一个驼峰或者低谷
    for(int i=0;i=nums[i+1]){
            if(flag){
                if(i-1<0||nums[i+1]>nums[i-1]) flag=false;//遇到的是驼峰
                else if(i+2>=numsSize||nums[i+2]>nums[i]) flag=false;//遇到的是低谷
                else return false;
            }else{
                //第二次遇到
                return false;
            }
        }
    }
    return true;
}

1979.找出数组的最大公约数

        排序+辗转相除法

int gcd(int x,int y){
    //辗转相除法
    if(y==0){
        return x;
    }
    return gcd(y,x%y);
}
int cmp(void* a,void *b){
    return *(int*)a-*(int*)b;
}
int findGCD(int* nums, int numsSize) {
    qsort(nums,numsSize,sizeof(int),cmp);//排序
    return gcd(nums[0],nums[numsSize-1]);
}

1991.找到数组的中间位置

        关键是左右侧元素相等即为 sum=total−nums[i]−sum

int findMiddleIndex(int* nums, int numsSize) {
    //左右侧元素相等即为 sum=total−nums[i]−sum
    int total=0;
    for(int i=0;i

2049.找出3位偶数

        要点:3位数,偶数,且三个数字要不同,第一个数字不能是0,且不能有重复的答案,最后输出必须按升序排序

class Solution {
public:
    vector findEvenNumbers(vector& digits) {
        unordered_set s;//用于去重
        int n=digits.size();
        for(int i=0;i res;
        for(int num:s){
            res.push_back(num);
        }
        sort(res.begin(),res.end());
        return res;
    }
};

2239.查找最接近0的数字

        1.第一次想法:比较复杂,还用了排序,就是找正负交替的那来两个数
int cmp(void* a,void*b){
    return *(int*)a-*(int*)b;
}
int findClosestNumber(int* nums, int numsSize) {
    qsort(nums,numsSize,sizeof(int),cmp);
    int index=0;//第一个为正的数字
    while(indexabs(nums[index-1])){
        return nums[index-1];
    }
    return nums[index];
}
        2.想法二:就是找绝对值最小的数,直接一次遍历查找,用一个变量dis进行记录绝对值
int findClosestNumber(int* nums, int numsSize) {
   int res=nums[0];
   int dis=abs(nums[0]);
   for(int i=1;ires){
               res=nums[i];
           }
       }
   }
   return res;
}

 2357.使数组中所有元素都等于0的最小操作次数

        1.方法一:模拟,每次找出数组中的最小正数,然后依次减去该数,再判断当前数组中的最小正数
int fun(int *nums,int numsSize){
    //找出最小正数
    int mm=INT_MAX;
    for(int i=0;i0&&nums[i]
         2.方法二:哈希

        由于每次减去一个数组中的最小的正数,只有当正数不相同时,需要操作的次数才会增加,因此问题转化为了找数组中有几个不同的正数。

class Solution {
public:
    int minimumOperations(vector& nums) {
        unordered_set s;//set天然去重
        for(int num:nums){
            if(num>0){
                s.emplace(num);
            }
        }
        return s.size();
    }
};

2395.两个和不相等的子数组

         1.法一:暴力法两次循环
bool findSubarrays(int* nums, int numsSize) {
    for(int i=0;i
        2.法二:哈希表 
class Solution {
public:
    bool findSubarrays(vector& nums) {
        unordered_set s;
        for(int i=0;i

2389.和有限的最长子序列

        1、暴力解,排序后模拟
class Solution {
public:
    vector answerQueries(vector& nums, vector& queries) {
        vector res;
        sort(nums.begin(),nums.end());
        for(int target:queries){
            int ans=0;
            int sum=0;
            for(int i=0;itarget){
                    ans--;
                    break;
                }
            }
            res.push_back(ans);
        }
        return res;
    }
};
        2、排序后求前缀和,再进行二分查找
class Solution {
public:
    vector answerQueries(vector& nums, vector& queries) {
        vector res;
        sort(nums.begin(),nums.end());
        for(int i=1;i

2404.出现最频繁的偶数

        用数组做哈希表,数字很大,占用空间不小。

int mostFrequentEven(int* nums, int numsSize) {
    int flag[100002]={0};
    int res=-1;
    int mmax=0;
    for(int i=0;immax||flag[nums[i]]==mmax&&nums[i]

 2108.找出数组中的第一个回文字符串

        判断回文字符串,然后遍历判断。

class Solution {
public:
    bool fun(string str){
        int n=str.size();
        for(int i=0;i& words) {
        for(string str:words){
            if(fun(str)){
                return str;
            }
        }
        return "";
    }
};

2154.将找到的值乘以2

给你一个整数数组 nums ,另给你一个整数 original ,这是需要在 nums 中搜索的第一个数字。

接下来,你需要按下述步骤操作:

  1. 如果在 nums 中找到 original ,将 original 乘以 2 ,得到新 original(即,令 original = 2 * original)。
  2. 否则,停止这一过程。
  3. 只要能在数组中找到新 original ,就对新 original 继续 重复 这一过程

        此题用递归的思想。代码简洁,但开销较大。 

int findFinalValue(int* nums, int numsSize, int original) {
    for(int i=0;i

2164.对奇偶下标分别进行排序

        模拟,用两个数组分别记录奇偶下标的元素,分别进行排序之后,在写回nums数组中。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 int cmp1(int *e1,int *e2) {
     //降序
    return *e2 - *e1;
}
int cmp2(int *e1,int *e2) {
    //升序
    return *e1 - *e2;
}
int* sortEvenOdd(int* nums, int numsSize, int* returnSize){
    *returnSize = numsSize;
    int n=(numsSize+1)/2;
    int odd[n],even[n],len1 = 0,len2 = 0,i;
    // 取出奇数和偶数
    for (i = 0; i < numsSize; i++) {
        if (i%2==1) {
            odd[len1++] = nums[i];
        } else {
            even[len2++] = nums[i];
        }
    }
    qsort(odd,len1,sizeof(int),cmp1);
    qsort(even,len2,sizeof(int),cmp2);
    for (i = len1 = len2 = 0; i < numsSize; i++) {
        if (i%2==1) nums[i] = odd[len1++];
        else nums[i] = even[len2++];
    }
    return nums;
}

2185.统计包含指定前缀的字符串

         对字符串进行操作,复习strncmp()函数:

int strncmp(const char *str1, const char *str2, size_t n) 把 str1 和 str2 进行比较,最多比较前 n 个字节。

返回值为:

  • 按照ASCII值进行比较,str1-str2的数值就是返回值。
  • 如果返回值 < 0,则表示 str1 小于 str2
  • 如果返回值 > 0,则表示 str2 小于 str1
  • 如果返回值 = 0,则表示 str1 等于 str2
int prefixCount(char** words, int wordsSize, char* pref) {
    int res=0;
    int len=strlen(pref);
    for(int i=0;i

2210.统计数组中的峰和谷的数量

        此题的难点的是需要跨越多个值进行判断峰和谷,相等的数字应该跳过,需要比较的是不同的值。

int countHillValley(int* nums, int numsSize) {
    //从三个数中去找小于或大于两边的数组的个数,若数对中有两个数相等,就跳过相等的数去寻找下一个不相等的数由此构成新的数对,再判断是否符合条件
    int ans=0;
    int temp=nums[0];
    for(int i=1;inums[i+1]&&nums[i]>temp){//遇到峰,ans加1
            ans++;
        }else if(nums[i]

2016.增量元素之间的最大差值

题目:给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i] 能求得的 最大差值 ,其中 0 <= i < j < n 且 nums[i] < nums[j] 。

返回 最大差值 。如果不存在满足要求的 i 和 j ,返回 -1 。

        1.暴力解 
int maximumDifference(int* nums, int numsSize) {
    int ans=-1;
    for(int i=0;i0&&cur>ans){
                ans=cur;
            }
        }
    }
    return ans;
}
        2.前缀和 
int maximumDifference(int* nums, int numsSize) {
    int ans=-1;
    int premin=nums[0];
    for(int i=1;ipremin){
            if(nums[i]-premin>ans){
                ans=nums[i]-premin;//ans=max(ans,nums[i]-premin)
            }
        }else{
            premin=nums[i];
        }
    }
    return ans;
}

你可能感兴趣的:(leetcode刷题打卡,算法,数据结构,java)