LeetCode Hot100 回顾(二)

子串

560.和为K的子数组

使用前缀和预处理一下题目给的数组, 然后用二重循环遍历一遍就可以了。

239.滑动窗口最大值

看题面比较容易想到的是用优先级队列来解决, 但是STL中的priority_queue不支持随机删除, 如果要用优先级队列来解决这道题的话比较复杂。这道题的一种正确解法是用单调队列来处理, 单调队列专门用来处理类似滑动窗口的区间最值问题。

接下来来看针对这道题, 单调队列是如何处理元素的入队和出队呢?

  • 入队: 从队列的后方入队, 弹出所有比当前元素(即待入队元素)小的元素, 因为这些元素都比当前元素小, 而且入队时间更早, 如果队列中有当前元素, 那么这些较小的元素永远不可能成为答案
  • 出队: 从队列的前方出队, 先弹出所有已经在区间外的元素, 然后得到的队头即是当前窗口的最大值
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        deque<int> que;  // 出队从前面, 入队从后面
        for (int i = 0; i < k; ++i) {
            while(!que.empty() && nums[i] > nums[que.back()]) que.pop_back();
            que.push_back(i);
        }
        res.push_back(nums[que.front()]);
        for (int i = k; i < nums.size(); ++i) {  // 枚举区间右端点
            while(!que.empty() && nums[i] > nums[que.back()]) que.pop_back();
            que.push_back(i);
            while(que.front() <= i-k) {
                que.pop_front();
            }
            res.push_back(nums[que.front()]);
        }
        return res;
    }
};

这类区间最值问题还可以使用ST表或线段树来解决, 不过针对滑动窗口的区间最值问题, 还是单调队列更简便一些。

普通数组

53.最大子数组和

从前往后遍历, 用一个变量来记录和, 如果这个变量记录到的和小于0, 就将它重置为0; 因为它不会给答案带来正面的收益, 算上它之后数组的和只会更小。注意要处理全是负数的数组的情况, 此时答案就为数组中最大的负数。

56. 合并区间

刚开始打算使用使用一个大小为1e4的数组来标记区间, 但是发现这种方法不能处理[1, 4], [5, 7]的例子, 这个例子实际没有产生重叠, 但依旧会在数组中产生一个连续的不为0的区间。正确处理方式是对所有区间按照左端点进行排序, 然后就可以方便的进行合并操作了。

189.轮转数组

使用区间拷贝的库函数, 几行就搞定了。空间复杂度为O(1)的方法可以通过旋转数组来实现。

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        k %= nums.size();
        vector<int> tmp(nums.rbegin(), nums.rbegin()+k);
        copy(nums.begin(), nums.end()-k, nums.begin()+k);
        copy(tmp.rbegin(), tmp.rend(), nums.begin());
    }
};

238.除自身以外数组的乘积

预处理前缀乘积和后缀乘积即可, 其中一个预处理数组可以使用一个变量来简化, 另一个预处理数组可以使用返回结果数组来代替。

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int> res(nums.size());
        res[0] = 1;
        for (int i = 0; i < nums.size()-1; ++i) {
            res[i+1] = res[i] * nums[i];
        }
        int t = 1;
        for (int i = nums.size()-1; i >= 0; --i) {
            res[i] *= t;
            t *= nums[i];
        }
        return res;
    }
};

矩阵

73.矩阵置零

直接说进阶方法,用第1行和第1列来记录第i行/第j列是否需要置零,第1行和第1列是否需要置0可以使用两个标志变量来记录。

54.螺旋矩阵

我采用了一种类似分治的想法,通过一个循环来不断输出数组,在循环的过程中,每输出一整行,剩下需要输出的矩阵的高就减1;同样每输出一整列,剩下需要输出的矩阵的宽就减1,直到剩余矩阵的宽或高变为0时,输出就结束了。通过一个变量来标记当前输出的方向。

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> res;
        int height = matrix.size();
        int width = matrix[0].size();
        pair<int, int> pos(0, 0);
        /**
         *  移动方向
         * 1 --- 横向增大
         * 2 --- 纵向增大
         *
         * -1 --- 横向减小
         * -2 --- 纵向减小
         */
        int dir = 1;
        while(height && width) {
            if (dir == 1) {
                for (int i = 0; i < width; ++i) {
                    res.push_back(matrix[pos.first][pos.second+i]);
                }
                --height;
                pos.second += width-1;
                pos.first += 1;
                dir = 2;
            } else if (dir == 2) {
                for (int i = 0; i < height; ++i) {
                    res.push_back(matrix[pos.first+i][pos.second]);
                }
                --width;
                pos.first += height-1;
                pos.second -= 1;
                dir = -1;
            } else if (dir == -1) {
                for (int i = 0; i < width; ++i) {
                    res.push_back(matrix[pos.first][pos.second-i]);
                }
                --height;
                pos.second -= width-1;
                pos.first -= 1;
                dir = -2;
            } else if (dir == -2) {
                for (int i = 0; i < height; ++i) {
                    res.push_back(matrix[pos.first-i][pos.second]);
                }
                --width;
                pos.first -= height-1;
                pos.second += 1;
                dir = 1;
            }
        }
        return res;
    }
};

48.旋转图像

矩阵旋转90度,只需要沿对角线翻转矩阵,然后把矩阵逐行逆序即可。

240.搜索二维矩阵

遍历所有列, 二分查找。看了三叶的评论, 发现这个矩阵可以抽象成根节点在矩阵右上角的二叉搜索树, 太妙了。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {  // 抽象成二叉搜索树
        pair<int, int> pos{0, matrix[0].size()-1};
        while(true) {
            if (target > matrix[pos.first][pos.second]) {  // 往右子树查找
                if (pos.first == matrix.size()) return false;
                ++pos.first;
            } else if (target < matrix[pos.first][pos.second]) {
                if (pos.second == 0) return false;
                --pos.second;
            } else {
                return true;
            }
        }
        return false;
    }
};

链表

160.相交链表

可以知道, 如果两个链表相交, 那么从链表的末尾到相交节点的距离一定是相等的, 我们在遍历两个链表的过程中, 可以先将指针移动到距离链表结尾距离相等的位置, 然后同时移动两个指针, 移动过程中查看两个指针是否指向了同一个节点。

206. 翻转链表

头插法即可。这里学习一下如何使用递归来完成翻转, 这里的递归和以前用到的递归形式不太一样, 不太好理解

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (!head || !head->next) return head;
        ListNode* p = head;
        ListNode* newHead = reverseList(head->next);  // (1)假设head后的所有节点都完成了翻转
        head->next->next = head;  // (2)翻转后head的下一个节点变成了head前面紧邻的节点
        head->next = nullptr;  // (3)head->next置空
        return newHead;  // 返回翻转后的新头节点
    }
};

我们现在取一个中间状态来讲解一下,假设现在递归调用到了处理节点2的情况,执行完(1)后链表的情况是这样的

执行完(2)之后链表情况是这样的

执行完(3)之后是这样的

234.回文链表

判断回文串的方式就是找到中间节点, 使用两个指针分别向两边移动, 依次比较即可, 难点主要在链表不能简单的找到它的前驱节点, 我们可以利用递归函数的性质来比较

class Solution {
private:
    ListNode* p;
    int pos;
public:
    bool isPalindrome(ListNode* head) {
        ListNode* slow = head, *fast = head;
        pos = 0;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
            ++pos;
        }
        if (fast) p = slow->next;
        else p = slow;
        return cmp(head, 0);
    }
    bool cmp(ListNode* head, int cnt) {
        if (cnt < pos) {
            if (cmp(head->next, cnt+1)) {
                if (head->val == p->val) {
                    p = p->next;
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/360016.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode刷题(剑指offer) 82.删除排序链表中的重复元素Ⅱ

82.删除排序链表中的重复元素Ⅱ 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2,5]示例 2&#xff1a…

数据监测的频次应如何设定

品牌在做控价时&#xff0c;需要先对线上数据进行监测&#xff0c;监测就要考虑监测的时间点&#xff0c;是白天监测还是夜晚监测&#xff0c;或者一天要监测几轮&#xff0c;这些问题都需要提前考虑好&#xff0c;因为待监测结果出来还要做破价治理&#xff0c;所以时间结点必…

PyCharm安装教程(超详细),零基础小白也能看懂

一、简介 PyCharm是一款Python IDE&#xff0c;其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如&#xff0c; 调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制等等。此外&#xff0c;该IDE提供了一些高级功…

DAIL-SQL:LLM在Text-to-SQL任务中的详细评估

导语 本文聚焦于利用LLMs进行Text-to-SQL任务&#xff0c;并指出缺乏系统性基准测试限制了有效、高效和经济的LLM-based Text-to-SQL解决方案的发展。研究者首先系统地比较了现有的提示工程方法&#xff0c;并分析了它们的优缺点。基于这些发现&#xff0c;提出了一个新的综合…

高等数学基础【1】极限与连续

第一节 函数 一、基本概念 ①函数 设变量x的取值范围为D,若对任意的x∈D,按照某种对应关系总有唯一确定的值y与x对应,称y为x的函数,记为yf(z),其中D称为函数yf(x)的定义域 ②复合函数 设uφ(x)(x∈D1),yf(u)(u∈D,),且对任意的x∈D1有φ(x)∈D2,称y为x的复合函数,记为yf[φ…

iText操作pdf

最近有个任务是动态的创建pdf根据获取到的内容&#xff0c;百度到的知识点都比较零散&#xff0c;官方文档想必大家也不容易看懂。下文是我做出的汇总 public class CreatePdfUtils {public static void create(){//准备File file new File("C:\\code\\base-project-back…

pytorch学习笔记(十二)

以下代码是以CIFAR10这个10分类的图片数据集训练过程的完整的代码。 训练部分 train.py主要包含以下几个部件&#xff1a; 准备训练、测试数据集用DateLoader加载两个数据集&#xff0c;要设置好batchsize创建网络模型&#xff08;具体模型在model.py中&#xff09;设置损失函…

【大数据】Flink SQL 语法篇(三):窗口聚合(TUMBLE、HOP、SESSION、CUMULATE)

Flink SQL 语法篇&#xff08;三&#xff09;&#xff1a;窗口聚合 1.滚动窗口&#xff08;TUMBLE&#xff09;1.1 Group Window Aggregation 方案&#xff08;支持 Batch / Streaming 任务&#xff09;1.2 Windowing TVF 方案&#xff08;1.13 只支持 Streaming 任务&#xff…

自己实现的小功能

小功能实现 2024/1/31 问题一&#xff1a; 将文本模式的csv文件作为表编辑之后&#xff0c;先要再变回来。找了5分钟都没找到&#xff0c;去网上搜也没搜到 解决方案 复制一份&#xff0c;对没错。 不是把表遍历一遍&#xff0c;重新将数据写入。 3.5给的答案就是重新写入…

网络防御基础介绍和基本的策略集

1.什么是防火墙 防火墙的主要职责在于&#xff1a;控制和防护 --- 安全策略 --- 防火墙可以根据安全策略来抓取流量之后做出对应的动作。 2.防火墙的分类 防火墙吞吐量 --- 防火墙同一时间处理的数据量 3.防火墙的历史 4.防火墙的分类 1.基于数据包的防火墙-包过滤防火墙 缺…

深度学习(9)--pydot库和graphviz库安装流程详解

目录 一.pydot库安装 二.graphviz库安装 一.pydot库安装 pydot的安装可直接在编译器安装相关包&#xff0c;以PyCharm举例&#xff1a; 如果搜索可用软件包显示为空&#xff0c;记得在此处把使用Conda软件包管理器”点亮 二.graphviz库安装 点击链接下载安装包graphviz-2.38…

网络协议与攻击模拟_11DHCP欺骗防护

开启DHCP 监听 ip dhcp snooping 指定监听vlan ip dhcp snooping vlan 1 由于开启监听后&#xff0c;交换机上的接口就全部变成非信任端口&#xff0c; 非信任端口会拒绝DHCP报文&#xff0c;会造成正常的DHCP请求和响应都无法完成。 现在是请求不到IP地址的&#xff0c;…

字符串匹配算法(BF、KMP)

一 字符串匹配算法—BF算法 BF算法简称暴力破解算法&#xff0c;时间复杂度很容易计算为O&#xff08;m*n&#xff09;(当n>>m时候) 本身字符串S&#xff0c;长度为m 模式字符串T,长度为n 最差情况&#xff0c;需要匹配(n-m)mm才可以成功&#xff0c;所以时间复杂度就是…

tarojs View多行文本无法换行问题解决

问题&#xff1a;未换行 code&#xff1a; 解决&#xff1a; 加上换行属性的css就好了 white-space: break-spaces;

银行ATM监控对讲系统分机可视对讲分机|ATM音视频终端IP网络可视对讲终端IP对讲终端对讲分机IP网络对讲系统

SV-6301T可视对讲终端 &#xff08;单键&#xff09; 产品简介 产品简介&#xff1a; 一键报警可视对讲终端是用于平安城市、银行、医院&#xff0c;智慧养老&#xff0c;景区&#xff0c;智慧路灯&#xff0c;平安校园&#xff0c;智慧电梯&#xff0c;无人超市等方案中的一…

哈希表算法模版

模拟散列哈希表 活动 - AcWing 拉链法 思路&#xff1a; 代码如下&#xff1a; #include <cstring> #include <iostream>using namespace std;const int N 1e5 3; // 取大于1e5的第一个质数&#xff0c;取质数冲突的概率最小 可以百度//* 开一个槽 h int h[…

jmeters响应结果反写csv文件及参数化

1.http响应结果反写csv文件 1.1各参数设置级别 线程组&#xff08;一级&#xff09;---->请求默认值、请求头、http请求、察看结果树&#xff08;二级&#xff09;----->正则表达式、BeanShell 后置处理程序&#xff08;三级&#xff09;。 1.2.正则表达式提取反写参数…

Backtrader 文档学习-Cheat-On-Open

Backtrader 文档学习-Cheat-On-Open 1.概述 V1.9.44.116增加了Cheat On Open的支持。对于全押的人来说&#xff0c;这似乎是一个必需的功能&#xff0c;用bar的收盘价后进行计算&#xff0c;希望与开盘价相匹配。 当开盘价差距&#xff08;上涨或下跌&#xff0c;取决于买入或…

SpringClound项目相关

nacos本机模式非虚拟机启动也可正常连接 nacos中的配置中心相当于在application.yml中的相关配置&#xff0c;转移位置&#xff0c;内容同application.yml完全一样均可。 黑马项目导入后&#xff0c;依赖缺失&#xff1a; 首先尝试maven重新加载&#xff0c;控制台提示传递依…

聊一聊GPT、文心、通义、混元

我使用同一个Prompt提示词“请以记叙文的文体来写”&#xff0c;分别发送给GPT-3.5&#xff08;调用API&#xff09;、文心、通义、混元&#xff0c;下面是它们各自生成的文本内容&#xff0c;大家一看便知了。 GPT-3.5&#xff1a; 在我个人使用GPT模型的过程中&#xff0c;我…