速刷算法#Day-01

刷算法,冲秋招,酱紫~

1. 二分查找

二分查找是一种高效的搜索算法,用于在有序数组中查找特定元素。该算法将搜索范围逐渐缩小一半,直到找到目标元素或确定不存在。

两个二分查找的实现示例,它们都采用了不同的处理边界和更新指针的方式。第一个示例中的 search 函数使用闭区间 [left, right] 进行搜索,而第二个示例中的 Division 函数使用左闭右开区间 [left, right) 进行搜索。这两种方式都是有效的,关键是正确地更新指针和边界,以确保不会陷入死循环并找到目标值。

cpp 复制代码
class Solution {
 
public:
    int search(vector<int>& nums,int target){
        int left=0,right=nums.size()-1;
        while(left<=right){

            int middle=(left+right)/2;

            cout<<middle<<endl;
            if(nums[left]==target) return left;

            if(nums[right]==target) return right;

            if(nums[middle]==target) return middle;

            if (nums[middle] > 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;
        }
    
};
cpp 复制代码
class Solution {

public:
    int Divsion(vector<int>& nums,int target){
        int left=0,right=nums.size()-1;
        while(left<right){

            int middle=(left+right)/2;

            cout<<middle<<endl;
            if(nums[left]==target) return left;

            if(nums[right]==target) return right;

            if(nums[middle]==target) return middle;

            if (nums[middle] > 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;
        }
}; 

2. 字符串反转

字符串反转是一种常见的操作,用于颠倒字符串中字符的顺序。提供了三种不同的实现方式,它们分别是:

  • 使用双指针法:从字符串两端向中间遍历,交换字符。
  • 使用标准库函数 reverse:直接调用标准库提供的字符串反转函数。(纯脑瘫)
  • 基于之前提供的反转方法。

这些方法都可以有效地反转字符串,关键是理解双指针法的原理以及如何正确地交换字符。

cpp 复制代码
class Solution{
public:
   void reverses(vector<char>& s){
    
    for(int i=0,j=s.size()-1;i<s.size()/2;i++,j--){
        swap(s[i],s[j]);
    }
   }
};
cpp 复制代码
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;
    }
};
cpp 复制代码
class Solution{
    public:
        void reverseString(vector<char>& s){
            //use reverse
            reverse(s.begin(), s.end());
        }
};

3. 移除元素

移除元素是指从数组中删除特定值的所有实例。提供了两种不同的实现方式,它们分别是:

  • 使用两个指针:一个快指针用于遍历数组,一个慢指针用于指向下一个非目标值的位置,将非目标值覆盖到慢指针所指的位置。
  • 使用单指针:遍历数组,当遇到非目标值时,将其复制到慢指针位置,并将慢指针右移。

这两种方式都是有效的,关键是正确地更新指针和数组元素,以达到移除目标元素的目的。

cpp 复制代码
class Solution{
    public:
        int removeElement(vector<int>& nums,int val){
            int size=nums.size();
            for(int i=0;i<size;i++){
                if(nums[i]==val){
                    for(int j=i+1;j<size;j++){
                        nums[j-1]=nums[j];
                    }
                    i--;
                    size--;
                } 
            }
        
        }
};
cpp 复制代码
class Solution{
    public:
        int removeElement(vector<int>& nums,int val){
            int slow=0;
            for(int fast=0;fast<nums.size();fast++){
                if(nums[fast]!=val){
                    nums[slow++]=nums[fast];
                }
           
            return slow; 
        }
};
cpp 复制代码
class Solution {
public:
    int removeElement(vector<int>& 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 现在指向了最终数组末尾的下一个位置
    }
};

4. 爬楼梯

爬楼梯是一个经典的动态规划问题,其中你需要计算爬到第 n 级楼梯的不同方法数。你提供了两种不同的实现方式,它们都使用动态规划来计算不同方法数。

第一个示例中的 climbStairs 函数使用数组来存储中间结果,从而避免重复计算。第二个示例中的 climbStairs 函数使用滚动数组的方式,只存储最近两个状态,进一步优化了空间复杂度。

cpp 复制代码
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n; // 因为下面直接对dp[2]操作了,防止空指针
        vector<int> 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];
    }
};
cpp 复制代码
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];
    }
};

5. 二叉树构建

用了前序遍历进行构造

cpp 复制代码
class TreeNode{
    public:
        int val;
        TreeNode *left;
        TreeNode *right;
        TreeNode(int x):val(x),left(NULL),right(NULL){}

    void traversal(TreeNode* cur,vector<int> & vec){
        if(cur==NULL)return;
        vec.push_back(cur->val);
        preorderTraversal(cur->left);
        preorderTraversal(cur->right);

    }

    vector<int> preorderTraversal(TreeNode *root){
        vector<int> vec;
        traversal(root,vec);
        return vec;
    }
};
相关推荐
云泽8081 分钟前
二叉树高阶笔试算法题精讲(二):非递归遍历与序列构造全解析
c++·算法·面试
无限进步_42 分钟前
C++ 多态机制完全解析:从虚函数重写到动态绑定原理
java·c语言·jvm·数据结构·c++·windows·后端
小O的算法实验室1 小时前
2026年ESWA,基于固定机巢的无人机输电杆塔、变电站与配电杆混合巡检任务分配与路径规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
sali-tec3 小时前
C# 基于OpenCv的视觉工作流-章60-点点距离
图像处理·人工智能·opencv·算法·计算机视觉
nlpming3 小时前
OpenCode Skills 文档
算法
无限进步_3 小时前
二叉搜索树完全解析:从概念到实现与应用场景
c语言·开发语言·数据结构·c++·算法·github·visual studio
05候补工程师4 小时前
深度解构 ROS 2:如何手动调通 Nav2 A* 路径规划引擎
linux·人工智能·经验分享·算法·机器人
上弦月-编程4 小时前
【C语言逻辑题】谋杀案凶手是谁?——经典矛盾推理题详解
算法
天若有情6734 小时前
逆向玩家狂喜!用C++野生写法一键破解线性加密(不规范但巨好用)
开发语言·c++·算法
风筝在晴天搁浅5 小时前
剑指Offer 60.n个骰子的点数
算法