[学习报告]《LeetCode零基础指南》(第四讲) 指针

本文分享了指针基础、内存理解与算法应用,如计数排序解决1365题的实例,探讨C++与Java中的vector使用技巧。重点讲解了动态计数和空间换时间优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

千山万水总有路,勇敢迈出第一步!!!

又是美好的一天呀,早上 5 点必须醒。我 always 不行~

言前面】指针很难 👈 反正大家都说难👉 本讲算法题,不难。想一下,本讲算法题,就下面这几个指针的知识点

  1. 声明时的 int*;   // TYPE_NAME* TYPE_NAME 类型的指针,固定格式
  2. 取值 *returnType = N;  // *POINT_NAME 获取指针存储的数组 
  3. 创建指针变量的 malloc(N*sizeof(TYPE_NAME))

一、吹逼

今日学习内容:指针,说难不难,说简单也难。大家都说难,我都不敢说简单了 ~ 【画几个内存图,指针瞎指指,DDDD】

是被 指针指来指去 的一天呀 ~~ (ˉ▽ ̄~) 切~~
每个算法不都是,写一句 malloc,写一句 *returnSize 吗?和指针有啥关系~ 

你要是用 C++、Java、Python、GO,就更加不用自己操作指针了。
BUT,数组是指针,数组名就是一个常量指针,这个要知道的呀~

今日最牛,统计下于当前数字的数字,英文题目:1365. how-many-numbers-are-smaller-than-the-current-number?【忍不住想要选 C 的一道英文选择题 🤦‍】

暴力枚举 → 计数排序:空间换时间算法的典范,范儿 👇 

class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        // 0 <= nums[i] <= 100
        // 统计 nums 中元素值出现的个数
        vector<int> cnt(101, 0);
        for(int i=0; i<nums.size(); i++) cnt[nums[i]] ++;

        // 利用动态和,统计小于等于当前下标值的元素个数
        cnt[0] ;    // 等于下标  0 的元素个数
        for(int i=1; i<cnt.size(); i++) {
            cnt[i] += cnt[i-1];
        }
        
        vector<int> ret;    // 统计结果
        for(int i=0; i<nums.size(); i++) {
            // 比 0 小的,不存在
            if(nums[i]==0) ret.push_back(0);
            // cnt 前一个下标的元素值,即为小于当前下标的元素总个数
            else ret.push_back(cnt[nums[i]-1]);
        }
        return ret;
    }
};

二、晒战绩

话不多说,上图~ 👇 没有想到吧,抓耳挠腮  全 绿题 

三、写解题报告

题解报告,只写让我有 

 的那道题!

先来 C++ vector 知识点,一直把 vector 当作数组来用,今天咱们尊重下 vector,学点知识:
>>> C++ vector 底层实现感兴趣的,看下 文1 文2

  1. 构造函数:vector<int> ret(nums);   // 深拷贝 nums,创建 ret
  2. 构造函数:vector<int> ret = {};   // 创建空 ret
  3. 构造函数:vector<int> ret(101, 0);   // 创建长度为 101,0 初始化的 ret
  4. 构造函数:vector<int> ret(101, 0);   // 创建长度为 101,0 初始化的 ret 
  5. 成员函数:vec.push_back();  // 入
  6. 成员函数:vec.pop_back();  // 出
  7. 成员函数:vec.size();  // vec 的容量
  8. 成员函数:vec.insert(index, e);  // e 插入到 index 处
  9. 成员函数:vec.begin();  // 前置迭代器 
  10. 运算符重载 []:vec[]  →  底层估计是 get(index) 啥的吧
    vector 只是重载了 [],底层是个数组 而已,而已,而已~ 

剑指 Offer 58 - II. 左旋转字符串:题目理解 → 字符串砍断,左面放右面,右面放左面。用 C 和 C++ 分别去实现,感受下 C 面向过程的魅力,同时,体会 C++ 基于面向对象的实现的算法、数据结构,有多好用~ 

// 上 C 👇
char* reverseLeftWords(char* s, int k){
    int n = strlen(s);
    char* ret = (char*)malloc((n+1) * sizeof(char));
    int j = 0;
    for(int i=k; i<n; i++,j++) ret[j] = s[i];
    for(int i=0; i<k; i++,j++) ret[j] = s[i];
    ret[n] = '\0';
    return ret;
}
// 下 C++ 👇
class Solution {
public:
    string reverseLeftWords(string s, int n) {
        return s.substr(n) + s.substr(0,n);
    }
};

1108. IP 地址无效化:题目理解 → 把 IP 地址那 三个点点,都用中括号包裹一下

// 上 C 👇
char * defangIPaddr(char * address){
    int N = strlen(address);
    char* ret = (char*)malloc((N+7) * sizeof(char));
    int i = 0;
    for(int j =0; j<N; j++) {
        if( address[j] == '.') {
            ret[i++]='[';
            ret[i++]='.';
            ret[i++]=']';
        }
        else ret[i++] = address[j];
    }
    ret[i] = '\0';
    return ret;
}
// 下 C++ 👇
class Solution {
public:
    string defangIPaddr(string address) {
        int cnt = 3;  // 只有三个点点~
        int idx = 0;
        while(cnt--) {
            idx = address.find('.', idx);
            address.replace(idx, 1, "[.]");
            idx += 3;  // 一个字符,变三个字符,原来 + 1,现在 + 3
        }
        return address;
    }
};

1365. 有多少小于当前数字的数字:题目理解 → 把数组中,所有小于当前元素的值,给我统计个数,按顺序整成数组

  1. 解法 1:暴力枚举,双层循环 👈 【伟大的先贤说过:先整对,再整快】
  2. 解法 2:空间换时间的典范,范儿 👇 计数排序 👉
    1. 具体思路,看一下注释,再次用到了动态和内容
// 👆 枚举 double loop 搞定一下子
class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        vector<int> ret(nums.size(), 0);
        for(int i=0;i<nums.size();i++) {
            for(int j=0;j<nums.size();j++) if(nums[j] < nums[i]) ret[i]++;
        }
        return ret;
    }
};
// 走计数 优化下 👇
class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        // 0 <= nums[i] <= 100
        // 统计 nums 中元素值出现的个数
        vector<int> cnt(101, 0);
        for(int i=0; i<nums.size(); i++) cnt[nums[i]] ++;

        // 利用动态和,统计小于等于当前下标值的元素个数
        cnt[0] ;    // 等于下标  0 的元素个数
        for(int i=1; i<cnt.size(); i++) {
            cnt[i] += cnt[i-1];
        }
        
        vector<int> ret;    // 统计结果
        for(int i=0; i<nums.size(); i++) {
            // 比 0 小的,不存在
            if(nums[i]==0) ret.push_back(0);
            // cnt 前一个下标的元素值,即为小于当前下标的元素总个数
            else ret.push_back(cnt[nums[i]-1]);
        }
        return ret;
    }
};

剑指 Offer 05. 替换空格: 题目理解 → 把字符串中的空格,替换成网址中的 %20。C 实现参考 非法IP。C++ 的 replace 方法,未提供批量替换功能,自定义一个 replace_all 

class Solution {
public:
    string& replace_all(string& str,const string& old_value,const string& new_value) {     
        while(true) {   
            string::size_type pos(0);    // 括号赋值 等价于 pos = 0;
            // find 函数找到不到指定子串时,返回 npos → 静态常量,-1
            if((pos=str.find(old_value))!=string::npos)     // string::npos 字符串尾指示器
                str.replace(pos,old_value.length(),new_value);     
            else break;
        }     
        return str;
    }
    
    string replaceSpace(string s) {
        return replace_all(s, " ", "%20");
    }
};

>>> 👆 C++ 作为 面向对象的先驱,真的是趟水坑🕳,字符串的实现,我懒得吐槽,只能好好学习 

四、写给明天

多美美好的一天呀~~ 喜刷刷,喜刷刷 😀😀😀 喜刷刷 刷刷~ 😀😀😀 ~ 

明早,不起了,反正起不来 (¬︿̫̿¬☆)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老坛算粉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值