目录
前言
跟着英雄哥打卡第三十一天
[专题跳转->《算法零基础100讲》]
[万人千题社区跳转]
一、判断子序列
跳转力扣:392. 判断子序列
难度:★☆☆☆☆
说明:双指针解决, s s s 表示短字符串, t t t 表示长字符串, i i i 记录短字符串的下标, j j j 记录长字符串下标,循环遍历 t t t , s [ i ] = = t [ j ] s[i]==t[j] s[i]==t[j]表示搜索到相同字符,此时短字符串向后走一步,当长字符串遍历结束后,指针 i i i 也到了最后则表示 s s s 为 t t t 的子序列
代码如下(示例):
class Solution {
public:
bool isSubsequence(string s, string t) {
int n = s.size(), m = t.size();
int i, j;
for (i = 0, j = 0; j < m; j ++) {
if (s[i] == t[j]) i ++;
}
return i == n;
}
};
二、搜索二维矩阵 II
跳转力扣:240. 搜索二维矩阵 II
难度:★☆☆☆☆
说明:优化暴力,由于数组每列向右递增,每行向下递增,以右上角为起点查找 t a r g e t target target ,若大于 t a r g e t target target ,则向左查找,若小于 t a r g e t target target ,则向下查找
代码如下(示例):
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m = matrix.size(), n = matrix[0].size();
int x = 0, y = n - 1;
while (x < m && y >= 0) {
if (matrix[x][y] > target)
y --;
else if (matrix[x][y] < target)
x ++;
else return true;
}
return false;
}
};
三、差的绝对值为 K 的数对数目
跳转力扣:2006. 差的绝对值为 K 的数对数目
难度:★☆☆☆☆
说明:哈希表,记录数字出现的次数,最后在数据范围内从小到大查找每个数字出现的次数和比之大k的值出现的次数的乘积
代码如下(示例):
class Solution {
public:
int countKDifference(vector<int>& nums, int k) {
unordered_map<int, int> hash;
int ans = 0;
for (auto &n: nums)
hash[n] ++; // 把列表中该数字的次数记录下来
for (int i = 1; i + k < 105; i ++) {
ans += hash[i] * hash[i + k]; // 由于给出num[i]的范围:1-100
// 则枚举数字从1到100数字,
// 哈希值乘积表示各自从中挑出多少个值进行比对
}
return ans;
}
};
四、找不同
跳转力扣:389. 找不同
难度:★☆☆☆☆
说明:哈希表, m s ms ms 表示 s s s 中每个字符出现的次数, m t mt mt 表示 t t t 中每个字符出现的次数,返回元素c,其中c在哈希表 m t mt mt 中比 m s ms ms 大 ,即添加的元素
代码如下(示例):
class Solution {
public:
char findTheDifference(string s, string t) {
unordered_map<char, int> ms, mt;
for (auto &c: s) ms[c] ++;
for (auto &c: t) {
mt[c] ++;
if (mt[c] > ms[c])
return c;
}
return ' ';
}
};
五、拥有最多糖果的孩子
跳转力扣:1431. 拥有最多糖果的孩子
难度:★☆☆☆☆
说明:贪心,先找到初始糖果数量最多的孩子,然后遍历每个孩子,如果现有全部糖果 e x t r a C a n d i e s extraCandies extraCandies 全部给这个孩子后,都比初始具有糖果数最多的孩子少,则返回false,否则为true
代码如下(示例):
class Solution {
public:
vector<bool> kidsWithCandies(vector<int>& candies, int extraCandies) {
int maxn = 0;
vector<bool> ans;
for (int i = 0; i < candies.size(); i ++)
maxn = max(maxn, candies[i]);
for (int i = 0; i < candies.size(); i ++) {
if (candies[i] + extraCandies < maxn)
ans.push_back(false);
else ans.push_back(true);
}
return ans;
}
};
六、所有奇数长度子数组的和
跳转力扣:1588. 所有奇数长度子数组的和
难度:★☆☆☆☆
说明:数学,计算在所有满足要求的子数组中每个数字出现的次数,遍历每一个数字,计算该数字左边有多少个数字 l e f t C o u n t leftCount leftCount ,右边有多少个数字 r i g h t C o u n t rightCount rightCount ,再分别计算左右两边连续奇数、偶数子数组的组数,计算可得结果
代码如下(示例):
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int sum = 0;
int n = arr.size();
for (int i = 0; i < n; i++) {
int leftCount = i, rightCount = n - i - 1; // 左边元素个数 右边元素个数
int leftOdd = (leftCount + 1) / 2; // 左边有多少个子数组个数为奇数
// 如若[1,2,3,4]为左边的元素,则[4]和[2,3,4]满足要求所需,即2个
int rightOdd = (rightCount + 1) / 2;
int leftEven = leftCount / 2 + 1; // 左边有多少个子数组个数为偶数
// 如若[1,2,3,4]为左边的元素,则[3,4]和[1,2,3,4]满足要求所需,即2个
int rightEven = rightCount / 2 + 1;
sum += arr[i] * (leftOdd * rightOdd + leftEven * rightEven);
}
return sum;
}
};
七、统计好三元组
跳转力扣:1534. 统计好三元组
难度:★☆☆☆☆
说明:暴力查找,若第一个数和第二个数不满足要求,直接跳过可节省时间
代码如下(示例):
class Solution {
public:
int countGoodTriplets(vector<int>& arr, int a, int b, int c) {
int n = arr.size(), ans = 0;
for (int i = 0; i < n; i ++) {
for (int j = i + 1; j < n; j ++) {
if (abs(arr[i] - arr[j]) > a) continue;
for (int k = j + 1; k < n; k ++) {
if (abs(arr[j] - arr[k]) <= b && abs(arr[i] - arr[k]) <= c)
ans ++;
}
}
}
return ans;
}
};
八、宝石与石头
跳转力扣:771. 宝石与石头
难度:★★☆☆☆
说明:集合,直接把题意翻译成代码,在遍历石头中如果有宝石就 + 1 +1 +1
代码如下(示例):
class Solution {
public:
int numJewelsInStones(string jewels, string stones) {
int jewelsCount = 0;
unordered_set<char> jewelsSet;
for (auto &jewel: jewels) {
jewelsSet.insert(jewel);
}
for (auto &stone: stones) {
if (jewelsSet.count(stone)) {
jewelsCount++;
}
}
return jewelsCount;
}
};
九、按既定顺序创建目标数组
跳转力扣:1389. 按既定顺序创建目标数组
难度:★★☆☆☆
说明:数组,直接调用数组的方法 i n s e r t ( p o s , n u m ) insert(pos, num) insert(pos,num) 在规定的下标pos插入数值num
代码如下(示例):
class Solution {
public:
vector<int> createTargetArray(vector<int>& nums, vector<int>& index) {
vector<int> ans;
for (int i = 0; i < nums.size(); i ++) {
ans.insert(ans.begin() + index[i], nums[i]);
}
return ans;
}
};
十、最长公共前缀
跳转力扣:14. 最长公共前缀
难度:★★☆☆☆
说明:哈希表,以第一个字符串 f i r s t first first 作为基底,将每个字符哈希,从第二个字符串开始遍历,计算每个字符串与 f i r s t first first 的前缀相同的最大值,然后在找出所有字符串计算出的最大前缀当中最小一个作为答案
代码如下(示例):
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (strs.size() == 1 ) return strs[0];
int hash[205], cnt = 0, ans = 205;
string first = strs[0];
while (cnt <= first.size()) {
hash[cnt ++] = first[cnt] - 'a';
}
for (int i = 1; i < strs.size(); i ++) {
int maxn = 0;
for (int j = 0; j < cnt && j < strs[i].size(); j ++) {
if (strs[i][j] - 'a' == hash[j])
maxn = max(maxn, j + 1);
else break;
}
ans = min(maxn, ans);
}
if (ans == 205) return "";
return first.substr(0, ans);
}
};
十一、统计平方和三元组的数目
跳转力扣:1925. 统计平方和三元组的数目
难度:★★☆☆☆
说明:暴力枚举,优化了三层循环,枚举了2个数后计算得到满足平方要求的第三个数,若第三个数也在 n n n 以内,则满足所有要求,计数器+1
代码如下(示例):
class Solution {
public:
int countTriples(int n) {
int res = 0;
// 枚举 a 与 b
for (int a = 1; a <= n; ++a){
for (int b = 1; b <= n; ++b){
// 判断是否符合要求
int c = int(sqrt(a * a + b * b));
if (c <= n && c * c == a * a + b * b){
++res;
}
}
}
return res;
}
};