一:插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
解答方法在另一篇博客:https://blog.csdn.net/qq_41631051/article/details/108378573
二:移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
解答方法在另一篇博客:https://mp.csdn.net/console/editor/html/108222712
三:赎金信
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
注意:
你可以假设两个字符串均只含有小写字母。
canConstruct("a", "b") -> false
canConstruct("aa", "ab") -> false
canConstruct("aa", "aab") -> true
分析:这道题的意思就是判断一个字符串ransom
中的字符是否在另一个字符串magazines中都有出现,我们首先用一个数组来统计magazines中每个字符出现的次数,然后遍历ransom
,当出现统计数组中的字符时,将其出现次数减一,如果ransom
中有字符不能在magazines中找到,那么其计数值会为负,此时就说明失败了。
代码如下:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
vector<int> v1(26,0);
for(auto s:magazine)
v1[s-'a']++;
for(int i=0;i<ransomNote.size();i++)
{
v1[ransomNote[i]-'a']--;
if(v1[ransomNote[i]-'a']<0)
return false;
}
return true;
}
};
四:长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组
解法一:
暴力法:遍历每个位置元素之后的数,计算其和,并更新最小长度
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int minLen=INT_MAX;
if(nums.size()==0) return 0;
for(int i=0;i<nums.size();i++)
{
int sum=0;
for(int j=i;j<nums.size();j++)
{
sum+=nums[j];
if(sum>=s)
{
minLen=min(minLen,j-i+1);
break;
}
}
}
return minLen==INT_MAX?0:minLen;
}
};
解法二:
定义两个指针start 和 end 分别表示子数组的开始位置和结束位置,维护变量sum 存储子数组中的元素和(即从 nums[start] 到 nums[end] 的元素和)。
初始状态下start 和 end 都指向下标 00,sum 的值为 00。
每一轮迭代,将nums[end] 加到 sum,如果 sum≥s,则更新子数组的最小长度(此时子数组的长度是end−start+1),然后将 nums[start] 从 sum 中减去并将start 右移,直到 sum<s,在此过程中同样更新子数组的最小长度。在每一轮迭代的最后,将 end 右移。
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int begin=0,end=0;
int sum=0;
int res=INT_MAX;
while(begin<=end)
{
sum+=nums[end];
if(sum>=s)
{
res=min(res,end-begin+1);
begin++;
end=begin;
}
else
{
end++;
}
}
return res==INT_MAX?0:res;
}
};
给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3
输出:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int count = 1; // 用来给矩阵中每一个空格赋值
int offset = 1; // 每一圈循环,需要控制每一条边遍历的长度
int i,j;
while (loop --) {
i = startx;
j = starty;
// 下面开始的四个for就是模拟转了一圈
// 模拟填充上行从左到右(左闭右开)
for (j = starty; j < starty + n - offset; j++) {
res[startx][j] = count++;
}
// 模拟填充右列从上到下(左闭右开)
for (i = startx; i < startx + n - offset; i++) {
res[i][j] = count++;
}
// 模拟填充下行从右到左(左闭右开)
for (; j > starty; j--) {
res[i][j] = count++;
}
// 模拟填充左列从下到上(左闭右开)
for (; i > startx; i--) {
res[i][j] = count++;
}
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
startx++;
starty++;
// offset 控制每一圈里每一条边遍历的长度
offset += 2;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2) {
res[mid][mid] = count;
}
return res;
}
};