[解题报告]《算法零基础100讲》(第31讲) 多维枚举(一) - 入门

目录

零、写在前面

一、主要知识点

二、课后习题 

392. 判断子序列

240. 搜索二维矩阵 II

2006. 差的绝对值为 K 的数对数目

389. 找不同

1431. 拥有最多糖果的孩子

1588. 所有奇数长度子数组的和

1534. 统计好三元组

771. 宝石与石头

1389. 按既定顺序创建目标数组

14. 最长公共前缀

1925. 统计平方和三元组的数目

写在最后


零、写在前面

        今天是打卡的第31天,今天的难度是不算高。知识点在:

《算法零基础100讲》(第31讲) 多维枚举(一) - 入门https://blog.csdn.net/WhereIsHeroFrom/article/details/121434597icon-default.png?t=LA92https://blog.csdn.net/WhereIsHeroFrom/article/details/121434597


一、主要知识点

        暴力yyds。。。。就硬搜 咋滴了0.0


二、课后习题 

392. 判断子序列

392. 判断子序列https://leetcode-cn.com/problems/is-subsequence/

题目描述

给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

思路

利用双指针进行搜索比较就好了0.0

bool isSubsequence(char * s, char * t){
    if(!t[0]&&!s[0])  return true;//空串判断
    else if(!t[0])  return  false;//空串判断
    int low = 0,high = 0;
    while(s[low]&&t[high]){
        while(t[high]&&s[low] != t[high]) high++;
        if(!t[high]) return false;    //t搜完了
        low++;high++;
    }
    if(!s[low]) return true;//low指针到头了
    return false;
}

240. 搜索二维矩阵 II

240. 搜索二维矩阵 IIhttps://leetcode-cn.com/problems/search-a-2d-matrix-ii/

题目描述

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  1. 每行的元素从左到右升序排列。
  2. 每列的元素从上到下升序排列。

思路

这个题目吧,我在剑指offer上写过。所以思路就是这本书里的。

常规思路肯定是从右下角元素进行排除,但是排除之后的过于复杂。

我们可以从左上角开始排除,如果大于这个元素就可以把一行排除,小于排除一列。

最终如果列小于0或者行大于最大值的时候结束。

bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target){
    int row = matrixColSize[0] -1,col = 0;
    while(row>=0 && col < matrixSize){
        if(matrix[col][row] > target)   row--;
        else if(matrix[col][row] < target)  col++;
        else return true;
    }
    return false;
}

2006. 差的绝对值为 K 的数对数目

2006. 差的绝对值为 K 的数对数目https://leetcode-cn.com/problems/count-number-of-pairs-with-absolute-difference-k/

题目描述

给你一个整数数组 nums 和一个整数 k ,请你返回数对 (i, j) 的数目,满足 i < j 且 |nums[i] - nums[j]| == k 。

|x| 的值定义为:

    如果 x >= 0 ,那么值为 x 。
    如果 x < 0 ,那么值为 -x 。

思路

这个题目吧,我之前写过,但是我对之前的不满意,因为和你们一样双循环暴力。

新思路是先对数组排序,然后用双指针去寻找满足条件的值。

需要注意的是如果扫描的值和之前的是一样需要加上次的计算结果。

时间复杂度就变成快排的O(nlogn)了,我是不是小机灵鬼?

int cmp(int *a,int *b){return *a > *b;}
int countKDifference(int* nums, int numsSize, int k){
    int ans = 0,temp = 0;//结果和临时变量保存之前的大小
    qsort(nums,numsSize,sizeof(int),cmp);//排序
    int low = 0,high = 0;//双指针
    while(high < numsSize || (low && low 

[解题报告]《算法零基础100讲》(第31讲) 多维枚举(一) - 入门_第1张图片可以把?


389. 找不同

389. 找不同https://leetcode-cn.com/problems/find-the-difference/

题目描述

给定两个字符串 st,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。

请找出在 t 中被添加的字母。

思路

这个题目吧,我之前写过,之前写的实在太强了,我都佩服我自己-.-

还记得异或的性质么。就是异或异或之后就抵消了。所以把所有元素全部异或一边不就得到了最终的值?

char findTheDifference(char * s, char * t){
        char ans = 0;
        for(int i = 0;s[i];i++)
            ans ^= s[i];
        for(int j = 0;t[j];++j)
            ans ^= t[j];
        return ans;
}

1431. 拥有最多糖果的孩子

1431. 拥有最多糖果的孩子https://leetcode-cn.com/problems/kids-with-the-greatest-number-of-candies/

题目描述

给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目。

对每一个孩子,检查是否存在一种方案,将额外的 extraCandies 个糖果分配给孩子们之后,此孩子有 最多 的糖果。注意,允许有多个孩子同时拥有 最多 的糖果数目

思路

这个题目需要先求出来最大值,然后分别判断就好了,注意空集的处理。

bool* kidsWithCandies(int* candies, int candiesSize, int extraCandies, int* returnSize){
    int max = 0;
    if(candiesSize == 0){    *returnSize = 0;return NULL;}
    *returnSize = candiesSize;
    bool *ans = malloc(sizeof(bool)*candiesSize);
    for(int i = 0; i < candiesSize;i++)    //求最大
        if(max < candies[i])     max = candies[i];
    for(int i = 0; i < candiesSize;i++)//计算结果
        ans[i] = (candies[i] + extraCandies >= max);
    return ans;
}

1588. 所有奇数长度子数组的和

1588. 所有奇数长度子数组的和https://leetcode-cn.com/problems/sum-of-all-odd-length-subarrays/

题目描述

给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。

子数组 定义为原数组中的一个连续子序列。

请你返回 arr 中 所有奇数长度子数组的和 。

思路

肯定有简单的方法,但是,不想想了,我直接暴力,三循环0.0

int sumOddLengthSubarrays(int* arr, int arrSize){
    int sum = 0;
    for(int len = 1; len <= arrSize; len += 2 )
        for(int start = 0; start +len <= arrSize; ++ start)
            for(int i = start; i < start + len; ++i)
                sum += arr[i];
    return sum;
}

1534. 统计好三元组

1534. 统计好三元组https://leetcode-cn.com/problems/count-good-triplets/

题目描述

给你一个整数数组 arr ,以及 a、b 、c 三个整数。请你统计其中好三元组的数量。

如果三元组 (arr[i], arr[j], arr[k]) 满足下列全部条件,则认为它是一个 好三元组 。

    0 <= i < j < k < arr.length
    |arr[i] - arr[j]| <= a
    |arr[j] - arr[k]| <= b
    |arr[i] - arr[k]| <= c

其中 |x| 表示 x 的绝对值。

返回 好三元组的数量 。

思路

肯定有简单的方法,但是,不想想了,我直接暴力,三循环0.0

int countGoodTriplets(int* arr, int arrSize, int a, int b, int c){
    int ans = 0;
    for(int i = 0;i < arrSize -2;i++)
        for(int j = i + 1;j < arrSize - 1;j++)
            for(int k = j + 1;k < arrSize;k++)
                if(abs(arr[i] - arr[j]) <= a && abs(arr[j] - arr[k]) <= b && abs(arr[i] - arr[k]) <= c) ans++;//满足条件判断
    return ans;
}

771. 宝石与石头

771. 宝石与石头https://leetcode-cn.com/problems/jewels-and-stones/

题目描述

 给你一个字符串 jewels 代表石头中宝石的类型,另有一个字符串 stones 代表你拥有的石头。 stones 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。

字母区分大小写,因此 "a" 和 "A" 是不同类型的石头。

思路

典型hash题,不解释。

int numJewelsInStones(char * jewels, char * stones){
    bool has[256];
    int ans = 0;
    memset(has, 0, sizeof(has));
    for(int i = 0; jewels[i]; ++i)//设置hash
        if(has[jewels[i]] == 0) has[jewels[i]] = 1;
    for(int i = 0; stones[i]; ++i)
        if(has[stones[i]] == 1) ans++;
    return ans;
}

1389. 按既定顺序创建目标数组

1389. 按既定顺序创建目标数组https://leetcode-cn.com/problems/create-target-array-in-the-given-order/

题目描述

给你两个整数数组 numsindex。你需要按照以下规则创建目标数组:

  • 目标数组 target 最初为空。
  • 按从左到右的顺序依次读取 nums[i]index[i],在 target 数组中的下标 index[i] 处插入值 nums[i]
  • 重复上一步,直到在 numsindex 中都没有要读取的元素。

请你返回目标数组。

题目保证数字插入位置总是存在。

思路

让干啥干啥就完事了。

void inserst(int *ans,int *size,int weizhi,int k){
    int wei = (*size)++;
    while(wei != weizhi)    ans[wei] = ans[wei - 1],wei--;
    ans[weizhi] = k;//插入
}
int* createTargetArray(int* nums, int numsSize, int* index, int indexSize, int* returnSize){
    int *ans = malloc(sizeof(int) * numsSize);
    *returnSize = 0;
    for(int i = 0;i < indexSize;i++)
        inserst(ans,returnSize,index[i],nums[i]);
    return ans;
}

14. 最长公共前缀

14. 最长公共前缀https://leetcode-cn.com/problems/longest-common-prefix/

题目描述

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

思路

按照一步一步求就好了。直接看把。

int qianzui(char *s,char *t,int size){//求两个字符串的公共前缀在第一个串的位置
    int i;
    for(i = 0;t[i] && i <= size;i ++)
        if(s[i]!= t[i]) return i - 1;
    if(!t[i])   return i - 1;
    return size;
}
char * longestCommonPrefix(char ** strs, int strsSize){
    if(strsSize < 2)    return strs[0];
    int size = strlen(strs[0])-1;
    size = qianzui(strs[0],strs[1],size);
    for(int i = 2;i

1925. 统计平方和三元组的数目

1925. 统计平方和三元组的数目https://leetcode-cn.com/problems/count-square-sum-triples/

题目描述

一个 平方和三元组 (a,b,c) 指的是满足 a2 + b2 = c2 的 整数 三元组 ab 和 c 。

给你一个整数 n ,请你返回满足 1 <= a, b, c <= n 的 平方和三元组 的数目。

思路

直接暴力刚0.0

int max( int a, int b){
    return a > b ? a : b;
}

int countTriples(int n){
    int a, b , c, sum, ans = 0, n1 = n /1.4;//根号2 嘿嘿黑 缩小范围
    for(int a = 1; a <= n1 ; ++a){
        for(b = a; b < n ; ++b){
            sum = a*a + b*b;
            for(c = max(a, b) +1; c <= n; c++){
                if(sum == c *c){
                    if(a !=b ) ans += 2;
                    else ans++;
                    break;
                }
                else if(sum < c*c)
                    break;
            }
        }
    }
    return ans;
}

写在最后

今天题挺多,难度不高。这周刷题刷完了就好好复习了,除了题解其他先暂停,也让自己稍微沉淀一下。感谢大家的关注!

 

你可能感兴趣的:(《算法零基础100讲》解题报告,算法,数据结构,c语言)