速刷算法#Day-01

 刷算法,冲秋招,酱紫~

1. 二分查找

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

两个二分查找的实现示例,它们都采用了不同的处理边界和更新指针的方式。第一个示例中的 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;
        }
}; 

2. 字符串反转

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

  • 使用双指针法:从字符串两端向中间遍历,交换字符。
  • 使用标准库函数 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());
        }
};

 

3. 移除元素

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

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

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

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 现在指向了最终数组末尾的下一个位置
    }
};

 

4. 爬楼梯

爬楼梯是一个经典的动态规划问题,其中你需要计算爬到第 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];
    }
};

 

5. 二叉树构建

用了前序遍历进行构造

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;
    }
};

你可能感兴趣的:(OJ,算法,leetcode,数据结构)