刷算法,冲秋招,酱紫~
二分查找是一种高效的搜索算法,用于在有序数组中查找特定元素。该算法将搜索范围逐渐缩小一半,直到找到目标元素或确定不存在。
两个二分查找的实现示例,它们都采用了不同的处理边界和更新指针的方式。第一个示例中的 search
函数使用闭区间 [left, right]
进行搜索,而第二个示例中的 Division
函数使用左闭右开区间 [left, right)
进行搜索。这两种方式都是有效的,关键是正确地更新指针和边界,以确保不会陷入死循环并找到目标值。
class Solution {
public:
int search(vector& nums,int target){
int left=0,right=nums.size()-1;
while(left<=right){
int middle=(left+right)/2;
cout< target) {
right = middle - 1; // target 在左区间,所以[left, middle - 1]
} else if (nums[middle] < target) {
left = middle + 1; // target 在右区间,所以[middle + 1, right]
} else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
class Solution {
public:
int Divsion(vector& nums,int target){
int left=0,right=nums.size()-1;
while(left target) {
right = middle; // target 在左区间,左闭右开,所以[left, middle ]
} else if (nums[middle] < target) {
left = middle + 1; // target 在右区间,所以[middle + 1, right]
} else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
字符串反转是一种常见的操作,用于颠倒字符串中字符的顺序。提供了三种不同的实现方式,它们分别是:
reverse
:直接调用标准库提供的字符串反转函数。(纯脑瘫)这些方法都可以有效地反转字符串,关键是理解双指针法的原理以及如何正确地交换字符。
class Solution{
public:
void reverses(vector& s){
for(int i=0,j=s.size()-1;i
class Solution{
public:
string reverseString(string s)
{
int i = 0, j = s.size() - 1;
while (i < s.size()/2)
{
swap(s[i++], s[j--]);
}
return s;
}
};
class Solution{
public:
void reverseString(vector& s){
//use reverse
reverse(s.begin(), s.end());
}
};
移除元素是指从数组中删除特定值的所有实例。提供了两种不同的实现方式,它们分别是:
这两种方式都是有效的,关键是正确地更新指针和数组元素,以达到移除目标元素的目的。
class Solution{
public:
int removeElement(vector& nums,int val){
int size=nums.size();
for(int i=0;i
class Solution{
public:
int removeElement(vector& nums,int val){
int slow=0;
for(int fast=0;fast
class Solution {
public:
int removeElement(vector& nums, int val) {
int leftIndex = 0; // 左指针从数组开头开始
int rightIndex = nums.size() - 1; // 右指针从数组末尾开始
while (leftIndex <= rightIndex) {
// 找左边等于val的元素,一直移动左指针
while (leftIndex <= rightIndex && nums[leftIndex] != val) {
++leftIndex;
}
// 找右边不等于val的元素,一直移动右指针
while (leftIndex <= rightIndex && nums[rightIndex] == val) {
--rightIndex;
}
// 如果左指针指向的位置在右指针左侧,将右指针指向的不等于val的元素覆盖左指针指向的等于val的元素
if (leftIndex < rightIndex) {
nums[leftIndex++] = nums[rightIndex--];
}
}
return leftIndex; // leftIndex 现在指向了最终数组末尾的下一个位置
}
};
爬楼梯是一个经典的动态规划问题,其中你需要计算爬到第 n 级楼梯的不同方法数。你提供了两种不同的实现方式,它们都使用动态规划来计算不同方法数。
第一个示例中的 climbStairs
函数使用数组来存储中间结果,从而避免重复计算。第二个示例中的 climbStairs
函数使用滚动数组的方式,只存储最近两个状态,进一步优化了空间复杂度。
class Solution {
public:
int climbStairs(int n) {
if (n <= 1) return n; // 因为下面直接对dp[2]操作了,防止空指针
vector dp(n + 1);
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) { // 注意i是从3开始的
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
};
class Solution {
public:
int climbStairs(int n) {
if (n <= 1) return n;
int dp[3];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
int sum = dp[1] + dp[2];
dp[1] = dp[2];
dp[2] = sum;
}
return dp[2];
}
};
用了前序遍历进行构造
class TreeNode{
public:
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
void traversal(TreeNode* cur,vector & vec){
if(cur==NULL)return;
vec.push_back(cur->val);
preorderTraversal(cur->left);
preorderTraversal(cur->right);
}
vector preorderTraversal(TreeNode *root){
vector vec;
traversal(root,vec);
return vec;
}
};