IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 力扣图解算法数据结构学习笔记C++篇 -> 正文阅读

[数据结构与算法]力扣图解算法数据结构学习笔记C++篇

图解算法数据结构

数据结构

剑指 Offer 05. 替换空格

题目要求:请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:

输入:s = "We are happy."
输出:"We%20are%20happy."

解法1-要点

重新定义数组长度:len = len+2*spaceNumber;

逆序修改数组内容;(逆序很重要)-(遇到字符,后移,遇到空格替换为%20[修改3个字符]);

解法1-代码

class Solution {
public:
    string replaceSpace(string s) {
        int count = 0, len = s.size();
        // 统计空格数量
        for (char c : s) {
            if (c == ' ') count++;
        }
        // 修改 s 长度
        s.resize(len + 2 * count);
        // 倒序遍历修改
        for(int i = len - 1, j = s.size() - 1; i < j; i--, j--) {
            if (s[i] != ' ')
                s[j] = s[i];
            else {
                s[j - 2] = '%';
                s[j - 1] = '2';
                s[j] = '0';
                j -= 2;
            }
        }
        return s;
    }
};

解法2-要点

采用string自带find查找位置。replace根据查找的位置替换为“%20”。

解法2-代码

class Solution {
public:
    string replaceSpace(string s) {
        int pos = -1;
        while (true)
        {	// 查找位置。每次查找的起始位置要在之前查找到位置加1
            pos = (int)s.find(' ', ++pos);
            if (pos < 0)
            {
                break;
            }
            // 替换
            s = s.replace(pos,1,"%20");	// 起始位置,替换数量,替换内容
        }

        return s;
    }
};

剑指 Offer 06. 从尾到头打印链表

解法1-要点

利用递归,先递推至链表末端;回溯时,依次将节点值加入列表,即可实现链表值的倒序输出。

解法1-代码

class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        recur(head);
        return res;
    }
private:
    vector<int> res;
    void recur(ListNode* head) {
        if(head == nullptr) return;
        recur(head->next);
        res.push_back(head->val);
    }
};

解法2-要点

链表只能 从前至后 访问每个节点,而题目要求 倒序输出 各节点值,这种 先入后出 的需求可以借助 来实现。

解法2-代码

class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        stack<int> stk;
        // 顺序入栈
        while(head != nullptr) {
            stk.push(head->val);
            head = head->next;
        }
        vector<int> res;
        // 出栈
        while(!stk.empty()) {
            res.push_back(stk.top());
            stk.pop();
        }
        return res;
    }
};

解法3-要点

采用数组存储。获取链表长度,链表顺序访问向数组逆序输入值。

解法3-代码

class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        int countNode = 0;
        ListNode* Lp = head;
        // 获取长度
        while(Lp!=NULL){
            Lp = Lp->next;
            countNode ++;
        }
        vector_int.resize(countNode);
        Lp = head;
        while(Lp!=NULL){
            vector_int[--countNode]=Lp->val;
            Lp = Lp->next;
        }

        return vector_int;
    }
private:
    vector<int> vector_int;
};

剑指 Offer 09. 用两个栈实现队列

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

解法-要点

两个栈,一个栈用来插入,一个栈用来删除。删除时将插入的栈全部元素移动到删除的栈中。

解法-代码

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

class CQueue {
public:
    CQueue()
    {
    }

    void appendTail(int value)
    {
        stack_tail.push(value);
    }

    int deleteHead()
    {
        int temp = 0;
        if (stack_head.empty())
        {
            // 将插入的栈的元素全部插入到推出的栈中
            while (!stack_tail.empty())
            {
                temp = stack_tail.top();
                stack_tail.pop();
                stack_head.push(temp);
            }
        }
        if (stack_head.empty())
        {
            return -1;
        }
        // 出栈 出队列
        temp = stack_head.top();
        stack_head.pop();
        return temp;
    }

private:
    stack<int> stack_head; // 表示推出的栈
    stack<int> stack_tail; // 表示插入的栈
};

剑指 Offer 20. 表示数值的字符串

题目
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

数值(按顺序)可以分成以下几个部分:

  1. 若干空格
  2. 一个 小数 或者 整数
  3. (可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数
  4. 若干空格

小数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符(’+’ 或 ‘-’)
  2. 下述格式之一:
    1. 至少一位数字,后面跟着一个点 ‘.’
    2. 至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
    3. 一个点 ‘.’ ,后面跟着至少一位数

整数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符(’+’ 或 ‘-’)

  2. 至少一位数字

部分数值列举如下:

["+100", “5e2”, “-123”, “3.1416”, “-1E-16”, “0123”]
部分非数值列举如下:

[“12e”, “1a3.14”, “1.2.3”, “±5”, “12e+5.4”]

解法-代码

采用状态转移图表示各种情况之间的关系。

解法-代码

class Solution {
public:
    bool isNumber(string s) {
        /* 状态转移表 */
        typedef pair<char, int> PCI;
        map<char, int> states[]{
            {PCI(' ', 0), PCI('s', 1), PCI('d', 2), PCI('.', 4)}, //  0. start with 'blank'
            {PCI('d', 2), PCI('.', 4)},                           // 1. 'sign' before 'e'
            {PCI('d', 2), PCI('.', 3), PCI('e', 5), PCI(' ', 8)}, // 2. 'digit' before 'dot'
            {PCI('d', 3), PCI('e', 5), PCI(' ', 8)},              // 3. 'digit' after 'dot'
            {PCI('d', 3)},                                        // 4. 'digit' after 'dot' (‘blank’ before 'dot')
            {PCI('s', 6), PCI('d', 7)},                           // 5. 'e'
            {PCI('d', 7)},                                        // 6. 'sign' after 'e'
            {PCI('d', 7), PCI(' ', 8)},                           // 7. 'digit' after 'e'
            {PCI(' ', 8)}};                                       // 8. end with 'blank'

        int p = 0;
        char t;
        for (char c : s)
        {
            if (c >= '0' && c <= '9')
                t = 'd';
            else if (c == '+' || c == '-')
                t = 's';
            else if (c == 'e' || c == 'E')
                t = 'e';
            else if (c == '.' || c == ' ')
                t = c;
            else
                t = '?';
            
            if (states[p].count(t) == 0) // 状态不存在退出
                return false;
            p = states[p][t];	// 状态转移
        }
        return p == 2 || p == 3 || p == 7 || p == 8;
    }
};

剑指 Offer 24. 反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

解法-要点

使用三个指针。一个存头节点cur,一个存放尾pre(新链表头),tmp一个暂存头节点的后一个。

解法-代码

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *cur = head, *pre = nullptr;
        while(cur != nullptr) {
            ListNode* tmp = cur->next; // 暂存后继节点 cur.next
            cur->next = pre;           // 修改 next 引用指向
            pre = cur;                 // pre 暂存 cur
            cur = tmp;                 // cur 访问下一节点
        }
        return pre;
    }
};

head, *pre = nullptr;
        while(cur != nullptr) {
            ListNode* tmp = cur->next; // 暂存后继节点 cur.next
            cur->next = pre;           // 修改 next 引用指向
            pre = cur;                 // pre 暂存 cur
            cur = tmp;                 // cur 访问下一节点
        }
        return pre;
    }
};

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 00:10:44  更:2021-07-24 00:10:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 4:39:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码