文章目录
前言
初识LeetCode与算法,将在此系列文章里面,记录自己的算法学习经历,前期主要是监督自己学习打卡,后期我会将自己对知识的理解,慢慢补充到文章当中,希望大家能在阅读我的文章中,有所收获。该系列文章的刷题顺序以代码随想录为线索。
一、二分查找
题目:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search
思路:
1、选择区间,选择是左闭右闭或者左闭右开,这个是代码的核心。
2、用到while、if-else if-else知识点
代码:
# 选择左闭右闭区间
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left <= right)
{
int middle = (left + right)/2;
if(nums[middle] > target)
{
right = middle - 1;
}
else if (nums[middle] < target)
{
left = middle + 1;
}
else
return middle;
}
return -1;
}
};
二、移除元素
题目:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search
思路:
1、写两个for循环,第一个for循环用来遍历,第二个for循环用来移动元素
2、双指针法,第一个快指针用来遍历,第二个慢指针用来指向数组下标
代码:
#双指针法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
int fastIndex = 0;
int size = nums.size();
for(fastIndex = 0; fastIndex < size ; fastIndex++)
{
if(val != nums[fastIndex])
{
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
三、有序数组的平方
题目:
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 已按 非递减顺序 排序
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search
思路:
1、直接将每个数组中的元素平方,之后再进行排序操作(直接掉用sort方法)
2、双指针法
代码:
#双指针法
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int> result(nums.size(), 0 );
for(int i = 0, j = nums.size() - 1; i <= j;)
{
if(nums[i] * nums[i] >nums[j] * nums[j])
{
result[k--] = nums[i] * nums[i];
i++;
}
else
{
result[k--] = nums[j] * nums[j];
j--;
}
}
return result;
}
};
四、长度最小的子数组
题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提示:
1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search
思路:
1、使用两个for循环,第一个循环用来遍历,第二个循环用来判断
2、滑动窗口法,使用两个指针,用一个循环来完成两个循环的作用。
代码:
#暴力解法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0;
int subLength = 0;
for(int i = 0; i<nums.size(); i++)
{
sum = 0;
for(int j = i; j<nums.size(); j++)
{
sum +=nums[j];
if(sum > target)
{
subLength = j - i + 1;
result = result < subLength ? result : subLength;
break;
}
}
}
return result == INT32_MAX ? 0 : result;
}
};
#滑动窗口法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0;
int j = 0;
int subLength = 0;
for(int i = 0; i<nums.size(); i++)
{
sum +=nums[i];
while(sum >= target) //这里是大于等于
{
subLength = i - j + 1;
result = result < subLength ? result : subLength;
sum -=nums[j++];
}
}
return result == INT32_MAX ? 0 : result;
}
};
五、螺旋矩阵 II
题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
提示:
1 <= n <= 20
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search
思路:
1、如何将此类问题建模是一个难点!
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n,0));
int startx = 0, starty = 0;
int loop = n/2;
int mid = n/2;
int count = 1;
int offset = 1;
int i,j;
while(loop--)
{
i = startx;
j = starty;
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++;
}
startx++;
starty++;
offset +=2;
}
if(n%2)
{
res[mid][mid] = count;
}
return res;
}
};
知识点补充
1、for循环知识,for循环语句中for()里面的条件判断:
2、vector容器和数组的区别:
vector可以理解为动态数组,数组理解为静态数组。
动态数组,即可以动态扩展,字面意思就是在原本数组后面再添加新的元素。但是需要注意的是:动态扩展并不是在原本的内存空间中扩展,而是将原来的数据拷贝到更大的内存空间中,同时释放原来的内存空间。
3、