目录
零、写在前面
一、主要知识点
二、课后习题
392. 判断子序列
240. 搜索二维矩阵 II
2006. 差的绝对值为 K 的数对数目
389. 找不同
1431. 拥有最多糖果的孩子
1588. 所有奇数长度子数组的和
1534. 统计好三元组
771. 宝石与石头
1389. 按既定顺序创建目标数组
14. 最长公共前缀
1925. 统计平方和三元组的数目
写在最后
今天是打卡的第31天,今天的难度是不算高。知识点在:
《算法零基础100讲》(第31讲) 多维枚举(一) - 入门https://blog.csdn.net/WhereIsHeroFrom/article/details/121434597https://blog.csdn.net/WhereIsHeroFrom/article/details/121434597
暴力yyds。。。。就硬搜 咋滴了0.0
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. 搜索二维矩阵 IIhttps://leetcode-cn.com/problems/search-a-2d-matrix-ii/
题目描述
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
思路
这个题目吧,我在剑指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 的数对数目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
389. 找不同https://leetcode-cn.com/problems/find-the-difference/
题目描述
给定两个字符串 s 和 t,它们只包含小写字母。
字符串 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. 拥有最多糖果的孩子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. 所有奇数长度子数组的和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. 统计好三元组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. 宝石与石头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. 按既定顺序创建目标数组https://leetcode-cn.com/problems/create-target-array-in-the-given-order/
题目描述
给你两个整数数组
nums
和index
。你需要按照以下规则创建目标数组:
- 目标数组
target
最初为空。- 按从左到右的顺序依次读取
nums[i]
和index[i]
,在target
数组中的下标index[i]
处插入值nums[i]
。- 重复上一步,直到在
nums
和index
中都没有要读取的元素。请你返回目标数组。
题目保证数字插入位置总是存在。
思路
让干啥干啥就完事了。
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. 最长公共前缀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. 统计平方和三元组的数目https://leetcode-cn.com/problems/count-square-sum-triples/
题目描述
一个 平方和三元组
(a,b,c)
指的是满足a2 + b2 = c2
的 整数 三元组a
,b
和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; }
今天题挺多,难度不高。这周刷题刷完了就好好复习了,除了题解其他先暂停,也让自己稍微沉淀一下。感谢大家的关注!