Leetcode刷题:空间缩减思想

不要再死刷LeetCode啦,先掌握这常用的八大算法思想再说!枚举、递推、递归、分治、动态规划、贪心、回溯、模拟 文章首发:微信搜索『业余码农』 算法和数据结构一直以来都是程序员的基本内功,可以说没有数据结构的基础建设和算法加持,也就没有这将近八十年的信息革命时代。数据结构可以看作是算法实现的容器,通过一系列特殊结构的数据集合,能够将算法更为高效而可靠的执行起来。 算法的应用不单只体现在编程中。狭义的来讲,算法可看作是数据传递和处理的顺序、方法和组成方式,就像是各种排序算法等。而广义的来讲,算法更像是一种事物运行的逻辑和规则。太阳东升西落,海水潮汐潮流,月儿阴晴圆缺,这些或许都可以看似一种算法,只不过执行者不是电子. 阅读详情


167. 两数之和 II - 输入有序数组

167. 两数之和 II - 输入有序数组

在这里插入图片描述
1. 二分

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {

        for (int i = 0; i < numbers.size(); i++) {
            int left = i + 1, right = numbers.size() - 1;
            while (left <= right) {
                int mid = (right + left) / 2;
                if (numbers[mid] < (target - numbers[i])) {
                    left = mid + 1;
                } else if (numbers[mid] > (target - numbers[i])) {
                    right = mid - 1;
                } else{
                    return {i+1, mid+1};
                }
            }
        }
        return {-1, -1};
    }
};

2. 双指针
空间缩减的思想:
一张图告诉你 O(n) 的双指针解法的本质原理(C++/Java) - 两数之和 II - 输入有序数组 - 力扣(LeetCode)

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int left = 0, right = numbers.size() - 1;
        while (left < right){
            if (numbers[left] + numbers[right] > target) {
                right--;
            } else if(numbers[left] + numbers[right] < target) {
                left++;
            } else {
                return {left + 1, right + 1};
            }
        }
        return {-1, -1};
    }
};

11. 盛最多水的容器

11. 盛最多水的容器

在这里插入图片描述


240. 搜索二维矩阵 II

240. 搜索二维矩阵 II

  =800x

我的答案

class Solution {
public:
    int position(vector<vector<int>>& matrix, int target, int r1, int r2, int c1, int c2, int situation) { //用b标记取大于等于还是小于等于
        int pos = -1;
        int mid = 0;
        if (r1 == -1 or r2 == -1 or c1 == -1 or c2 == -1) return -1;
        if (situation == 1) {
            int left = r1, right = r2;
            while (left <= right) {
                mid = (left + right) / 2;
                if (matrix[mid][c1] <= target && mid >= r1 && mid <= r2) {
                    left = mid + 1;
                    pos = mid;
                }
                else {
                    right = mid - 1;
                }
            }
        }
        else if (situation == 2) {
            int left = r1, right = r2;
            while (left <= right) {
                mid = (left + right) / 2;
                if (matrix[mid][c2] < target && mid >= r1 && mid <= r2) {
                    left = mid + 1;
                }
                else {
                    right = mid - 1;
                    pos = mid;
                }
            }
        }
        else if (situation == 3) {
            int left = c1, right = c2;
            while (left <= right) {
                mid = (left + right) / 2;
                if (matrix[r1][mid] <= target && mid >= c1 && mid <= c2) {
                    left = mid + 1;
                    pos = mid;
                }
                else {
                    right = mid - 1;
                }
            }
        }
        else {
            int left = c1, right = c2;
            while (left <= right) {
                mid = (left + right) / 2;
                if (matrix[r2][mid] < target && mid >= c1 && mid <= c2) {
                    left = mid + 1;
                }
                else {
                    right = mid - 1;
                    pos = mid;
                }
            }
        }
        return pos;
    }

    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if (matrix.size() == 1 && matrix[0].size() == 1) {
            if (matrix[0][0] == target) {
                return true;
            }
            else {
                return false;
            }
        }
        int r1 = 0, r2 = matrix.size() - 1, c1 = 0, c2 = matrix[0].size() - 1;
        int i = 0;
        while (i <= 300) {
            r1 = position(matrix, target, r1, r2, c1, c2, 2);
            r2 = position(matrix, target, r1, r2, c1, c2, 1);
            c1 = position(matrix, target, r1, r2, c1, c2, 4);
            c2 = position(matrix, target, r1, r2, c1, c2, 3);
            i++;
            if (r1 == -1 or r2 == -1 or c1 == -1 or c2 == -1) break;
            if (r1 >= r2 && c1 >= c2) break;
        }
        return (r1 >=0 && r2 >=0 &&c1 >=0 &&c2 >=0&& matrix[r1][c2] == target) ? true : false;
    }

};

从右上角开始单调性扫描

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = 0, n = matrix[0].size() - 1;
        while (m < matrix.size() && n >= 0) {
            if (matrix[m][n] < target) {
                m++;
            } else if (matrix[m][n] > target) {
                n--;
            } else {
                return true;
            }
        }
        return false;
    }
};

时间复杂度分析:

每一步会排除一行或者一列,矩阵一共有 n n n 行, m m m 列,所以最多会进行 n + m n+m n+m步。所以时间复杂度是 O ( n + m ) O(n+m) O(n+m)


11. 盛最多水的容器

11. 盛最多水的容器

暴力

class Solution {
public:
    int maxArea(vector<int>& height) {
        int m = 0;
        for (int i = 0; i < height.size(); i++) {
            for (int j = i + 1; j < height.size(); j++) {
                if ((j - i) * min(height[i], height[j]) > m) {
                    m = (j - i) * min(height[i], height[j]);
                }
            }
        }
        return m;
    }
};

空间缩减

class Solution {
public:
    int maxArea(vector<int>& height) {
        int l = 0, r = height.size() - 1;
        int m = (height.size() - 1) * min(height[l], height[r]);
        while (l < r) {
            if (height[l] < height[r]){
                l++;
                m = max(m, (r - l) * min(height[l], height[r]));
            } else {
                r--;
                m = max(m, (r - l) * min(height[l], height[r]));
            }
        }
        return m;
    }
};
证明

设有 l l l 和 r r r, l l l 位于 r r r 的左边,则:

当 l l l 位于最左, r r r 位于最右时:

  • 若 h [ l ] < h [ r ] h[l] <h[r] h[l]<h[r] ,则此时的面积取决于 h [ l ] h[l] h[l] 和 l , r l,r l,r 之间的距离,无论 r r r 如何移动,得到的面积都会小于最初的面积

  • 若 h [ l ] > h [ r ] h[l] >h[r] h[l]>h[r],则此时的面积取决于 h [ r ] h[r] h[r] 和 l , r l,r l,r 之间的距离,无论 l l l 如何移动,得到的面积都会小于最初的面积

一般情况下,面积为 m i n ( h [ l ] , h [ r ] ) ∗ ( r − l ) min(h[l],h[r])*(r-l) min(h[l],h[r])∗(r−l),若将较长边向内移动,只会改变 ( r − l ) (r-l) (r−l),不会改变 m i n ( h [ l ] , h [ r ] ) min(h[l],h[r]) min(h[l],h[r]),而如果改变较小的边,就有机会使 m i n ( h [ l ] , h [ r ] ) min(h[l],h[r]) min(h[l],h[r]) 变大。

也就是说,对于任意 l , r l,r l,r,将较长边向中间移动时,都不会出现面积变大的情况,可以被直接排除掉。只需要移动短边即可。

如果使面积最大的位置为 ( l , r ) (l, r) (l,r),则从 ( l , q ) , q > r (l,q),q>r (l,q),q>r移动到 ( l , r ) (l, r) (l,r)的过程中,所有 l l l右移得到的结果都被排除了

二分

对于每一个确定的水面高度,可以得到容器的最大宽度。使用二分法求最大宽度的位置

从左往右找到第一个大于等于h的位置;从右往左找到第一个大于等于h的位置

以求右端点为例:if 从mid到n这一段区间里的所有h[i][都比h矮,那么这一段都不可能成为答案,所以 r i g h t = m i d − 1 right = mid - 1 right=mid−1,else (这一段存在大于h的值)答案在这个区间内 l e f t = m i d + 1 left = mid + 1 left=mid+1

如何得到单调数组:求右端点时新建向量存放后缀最大值,如果某个位置高度小于h,其右所有高度都小于,可以直接排除

求左端点时存放前缀最大值

从零构建HFSS连接器仿真模型:以SMP接口的精准复现为例 本文详细介绍了如何从零构建HFSS连接器仿真模型,以SMP接口的精准复现为例。通过获取官方模型、导入技巧、信号路径提取和介质结构复现等步骤,帮助工程师避免常见错误,提升高频电路仿真的准确性。文章特别强调了模型精度对仿真结果的影响,并提供了实用的调试和管理建议。 阅读详情

相关推荐

three.js开发3D地图记录(二)

添加地图点击事件,点击区域,地图区域改变颜色并浮起来。

anwebDesigner的博客 1694

[LeetCode] Arithmetic Slices 等差数列的个数

声明:原题目转载自LeetCode,解答部分为原创 Problem :         A sequence of number is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements i

xblog_的博客 727

Linux显卡管理避坑指南:为什么Xorg总是占用你的NVIDIA GPU?

本文深入解析了在Linux系统上,尤其是双显卡笔记本中,Xorg显示服务器进程占用NVIDIA GPU的根本原因。文章从Xorg的驱动加载机制和NVIDIA驱动的独占性入手,详细对比了禁用配置文件、手动配置xorg.conf、使用官方PRIME方案以及切换到Wayland等主流解决方案的优缺点与适用场景,旨在帮助用户有效释放GPU资源,确保深度学习、游戏等计算任务能独占显卡性能。

xgboost6farmer的博客 268

Leetcode 115 Distinct Subsequences

题目:Given a stringSand a stringT, count the number of distinct subsequences ofSwhich equalsT.A subsequence of a string is a new string which is formed from the original string by deleting some (c...

ata_123的专栏 244

PDPS16.0单机版与SPLMLicenseServer授权避坑指南:从安装到冲突解决

本文详细解析了PDPS16.0单机版的安装与授权流程,重点阐述了如何正确配置SPLMLicenseServer本地许可证服务器以实现软件激活。针对安装过程中常见的许可证冲突问题,提供了清晰的排查思路和解决方案,并介绍了通过设置环境变量等替代授权方法,帮助用户高效避坑,确保Tecnomatix Process Simulate顺利运行。

weixin_29231221的博客 563

OpenClaw本地部署教程

本文详细介绍了在Windows 11系统上部署OpenClaw与Ollama本地模型的完整流程。主要内容包括:硬件要求说明、Node.js环境配置、Ollama模型安装与定制(重点扩展上下文窗口至32768 tokens)、OpenClaw核心框架安装与对接、常见问题解决(如模型上下文窗口过小报错)以及可选技能扩展和飞书接入方案。部署全程约需1-2小时,强调使用备用设备或虚拟机以确保安全,并提供关键配置参数和排错命令。该方案实现了"数据不出门、推理本地化"的私有化部署目标。

技术引领业务创新 2579

Leetcode 115. 不同的子序列 降低空间复杂度的解法

题目  给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。  字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,“ACE” 是 “ABCDE” 的一个子序列,而 “AEC” 不是)  题目数据保证答案符合 32 位带符号整数范围 示例1 输入:s = "rabbbit", t = "rabbit" 输出:3 解释: 如下图所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。 rabbbit rabbbit

qq_40405705的博客 921

2026华为OD面试题029:勇攀数字高峰

在给定的数字地形图里寻找登山路径,数字代表当前位置的海拔高度。要求从最低海拔出发,不断攀登,最终到达最高山峰。地图保证最低海拔和最高山峰都只有一个。 登山规则: - 路径上的海拔必须严格递增 - 只能向上下左右 4 个方向移动 - 路径必须从最低海拔开始,到最高海拔结束 - 每个地点只能走一次 - 每一步的攀登高度差必须大于 0,且不超过指定值 `K` 输出满足条件的登山路径的数量。

琅嬛福地 116

Leetcode 115. 不同的子序列

文章目录1.1 思路11.2 状态压缩2.1 思路22.2 状态压缩  给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,“ACE” 是 “ABCDE” 的一个子序列,而 “AEC” 不是) 题目数据保证答案符合 32 位带符号整数范围。  思路1:对于这种给定两个字符串的问题,类似于编辑距离和求最大公共子串,都可以采用动态规划。我们都可以设dp[i][j]dp[i][

weixin_43688483的博客 319

ximalaya 新xm-sign逆向思路

本文主要介绍目标网站新xm-sign值的逆向思路。仅代表个人理解,如有其他建议可在评论区沟通。声明仅仅记录一下自己的学习方法,不作为其他参考、更不作为商业用途。如有侵犯请联系本人删除。

weixin_66580433的博客 2017

nuScenes数据集详细介绍

nuScenes网上介绍资料较多,但是大部分仅仅是对官网的翻译,缺乏各个文件的内在联系介绍。例如,nuScenes激光雷达的数据格式,点云包含哪几种属性。再比如,sample文件夹和sweeps文件夹下的文件关系,以及是如何在相关json文件中体现的。本文将详细介绍nuScenes数据集的各个部分。

叶子的博客 1万+

LeetCode:实现数组等差的子数组的计数

题目描述: 给定一个数组,求这个数组中连续且等差的子数组一共有多少个.注意:这里的子数组 个数满足大于或等于3. 示例 1 Input:nums=[1,2,3,4] Output:3 在这个样例中,等差数列有:[1,2,3]、[2,3,4]和[1,2,3,4] 解题思路: 这道题要求等差数列,可以自然想到子树组必定满足: nums[i]-nums[i-1]=nums[i-1]-nums[i-2].然而由于对于dp数组的定义通常 以i结尾的,满足某些条件的子数组数量,而等差数列可以任意一个位置终结,因.

Jiangtagong的博客 651

cadence17.4和16.6同时安装无法使用的问题

经过对报错的问题分析,发现还是17.4的lic文件和16.6的不一样,16.6的版本总是无法找到自己对应的lic文件。卸载了,重新单独安装16.6,这里就是正确的。包括使用这些工具去修复这些问题,都无法接近。已经放弃了,使用哪个版本就安装 哪个版本。这个也无法解决问题。

D_Katter的博客 2324

【每日算法】理论:深度学习基础 刷题:力扣哈希表回顾

KL散度和JS散度在度量的时候有一个问题:如果p、q离得很远,完全没有重叠的时候,那么KL散度值是没有意义的,而JS散度值是一个常数。这在学习算法中是比较致命的,这就意味这这一点的梯度为0。JS散度度量了两个概率分布的相似度,基于KL散度的变体,解决了KL散度非对称的问题。问题类似,只不过需要多加一层循环。这两道题的关键难点在于不可以包含重复,因此在使用哈希法处理的时候有很多细节需要注意。问题可以先用两层for循环确定 a 和b 的数值,然后利用哈希法来确定 0-(a+b) 是否在 数组里出现过,而。

weixin_47748259的博客 1349

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

LeetCode 例题精讲 | 04 用双指针解 Two Sum:缩减搜索空间

点击关注上方“五分钟学算法”,设为“置顶或星标”,第一时间送达干货。转自面向大象编程本期例题:LeetCode 167 - Two Sum II - Input array is sor...

程序员吴师兄的博客 729

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

leetcode专题刷题计划

leetcode刷题计划

novincenotes的博客 185

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

leetcode 167 输入有序数组(双指针, 缩减搜索空间, c++)

题目描述: 直接上代码(代码都能看懂,接下来再说为什么代码是这样 ): class Solution { public int[] twoSum(int[] numbers, int target) { int low = 0; int high = numbers.length - 1; while (low < high) { int sum = numbers[low] + numbers[high];

qq_39786000的博客 234

LeetCode 热题 HOT 100 第7天: “盛最多水的容器”

继续刷LeetCode 热题 HOT 100 的题目,并且在博客更新我的solutions。在csdn博客中我会尽量用文字解释清楚,相关Java代码大家可以前往我的个人博客jinhuaiyu.com中查看。 做题不是为了做这道题,而是为了提取思想解决其他问题。今天的题目用到的思想和前几天都不一样,因此有必要深刻理解加深记忆。 题目:盛最多水的容器 给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和

qq_40967164的博客 351

Leetcode刷题零基础上手指南(Java语言描述)

愿所有解析拓宽你的思路! Array Two pointers同向 -> 用此方法处理过的数组,处理好的数据相对位置会保持一致 Two pointers反向 -> 数组不会保留相对位置 同向Step: 1.Initialize 2.while j < array.length ​ if we need array[j] , by assigning array[i] = array[j] //26 public int removeDuplicates(int[] arr)

This is Devinroot... 767

input 记住历史搜索_LeetCode 例题精讲 | 04 用双指针解 Two Sum:缩减搜索空间

本期例题:LeetCode 167 - Two Sum II - Input array is sorted[1](Easy)给定一个已按照升序排列的有序数组,找到两个数使得它们相加之和等于目标数(不可以重复使用同一个数),返回两个数的下标值 i 和 j,要求 i < j。假设每个输入有且仅有一个答案。示例:输入: numbers = [2, 7, 11, 15], target ...

weixin_27028523的博客 93

Python Leetcode刷题之双指针解题

双指针 双指针法,有时也叫快慢指针,在数组里是用两个整型值代表下标,在链表里是两个指针,一般能实现O(n)的时间解决问题,两个指针的位置一般在第一个元素和第二个元素或者第一个元素和最后一个元素,快指针在前“探路”,当符合某种条件时慢指针向前挪。 双指针还可以用来缩减搜索空间!!! 主要是将一头一尾的索引设为两个指针,当满足条件1时,头指针加一;当满足条件2时,尾指针减一;当满足条件3时,返回结果。多用于有序的数组(矩阵)中,可以有效降低算法的复杂度。 1.盛最多水的容器 class Solution:

qq_36103746的博客 373

力扣最热一百题——最长公共前缀

简单题的难度。难题的思路,全新解法,开拓思维,新手也能学会!!!

WenJGo的博客 1156

二分查找刷题总结

思路:因为每次都要缩减搜索空间,所以当isBadVersion返回true时,他的右边一定都为出错版本,左边还有可能有出错版本,他自己也可能是第一个出错的版本,所以r=mid,不可以排除潜在答案。split返回false时,分出的数组大于要求的m,证明我们的最大和过小,并且此时不可能为最后的解,l=mid+1.可视为模糊查找,查找第一个arr[mid]>arr[mid+1]的数,而n == 0 || n == arr.size()-1的情况直接被排除了,不可能为峰顶元素。输出这个最小的最大和。

Xuhaipeng1858的博客 217

[力扣刷题总结](双指针篇)

文章目录前言~~缩减搜索空间的思想~~11. 盛最多水的容器 前言 缩减搜索空间的思想 11. 盛最多水的容器 力扣链接 给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 说明:你不能倾斜容器。 示例 1: 输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,.

weixin_38800498的博客 4511

双指针(缩减搜索空间):力扣11. 盛最多水的容器

1、题目描述: 2、题解: 3、复杂的分析:

weixin_42042056的博客 182

LeetCode二分查找刷题分析与总结

2020/7/18 总结 总结:二分查找算法以及leetcode体型

ZHOUJIAN_TANK的博客 449
上一篇: Leetcode刷题:双指针
下一篇: 【笔记】Git及Github使用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值