leetcode热题 - 6

下标对中的最大距离

问题描述

给你两个 非递增 的整数数组 nums1​​​​​​ 和 nums2​​​​​​ ,数组下标均 从 0 开始 计数。

下标对 (i, j) 中 0 <= i < nums1.length 且 0 <= j < nums2.length 。如果该下标对同时满足 i <= j 且 nums1[i] <= nums2[j] ,则称之为 有效 下标对,该下标对的 距离 为 j - i​​ 。​​

返回所有 有效 下标对 (i, j) 中的 最大距离 。如果不存在有效下标对,返回 0 。

一个数组 arr ,如果每个 1 <= i < arr.length 均有 arr[i-1] >= arr[i] 成立,那么该数组是一个 非递增 数组。

(真题链接:下标对中的最大距离

解题思路

当看到题目的时候,我们能想到的最快的解法是挨个遍历一遍不就好了。但实际操作下来会发现:挨个遍历,即两层for循环会导致时间复杂度直接爆炸,无法通过。

这时候笔者就要介绍一个优化方法:双指针

我们可以定义两个指针,分别为ij,并让他们分别指向两个数组的首元素。因为整数数组是非递增的,且i <= j,所以ij的距离一定比i+1j的距离大。所以我们只需要先固定ij的初始位置,然后比较对应ij各个位置上的元素的大小,求出他们之间的距离即可。这种两个指针同时移动的方法,我们就叫做双指针。

代码实现

cpp 复制代码
class Solution {
public:
    int maxDistance(vector<int>& nums1, vector<int>& nums2) {
        int ret = 0;
        int i = 0, j = 0;
        // 优化:双指针
        for(i = 0, j = 0; i < nums1.size() && j < nums2.size();)
        {
            if(nums1[i] <= nums2[j])
            {
                ret = max(ret, j - i);
                j++;
            }
            else
            {
                i++;
                j++;
            }
        }
        return ret;
    }
};

复杂度分析

复杂度 量级
时间复杂度 O(n)
空间复杂度 O(1)

总结

本题给定两个非递增数组,需找出满足下标i ≤ jnums1[i] ≤ nums2[j]的最大下标距离;暴力双重循环效率过低,利用数组非递增的特性采用双指针解法,两个指针从头开始遍历,满足条件就更新最大距离并向后移动j,不满足则同时后移i和j,仅需一次遍历就能求解,时间复杂度为线性、空间复杂度为常量,是本题最优解题方式。

将1移动到末尾的最大操作次数

问题描述

给你一个 二进制字符串 s。

你可以对这个字符串执行 任意次 下述操作:

选择字符串中的任一下标 i( i + 1 < s.length ),该下标满足 s[i] == '1' 且 s[i + 1] == '0'

将字符 s[i] 向 右移 直到它到达字符串的末端或另一个 '1'。例如,对于 s = "010010",如果我们选择 i = 1,结果字符串将会是 s = "000110"。

返回你能执行的 最大 操作次数。

(真题链接:将1移动到末尾的最大操作次数

解题思路

该通过一次线性遍历 实现二进制字符串最大操作数的求解,核心逻辑为:初始化总操作数计数器cnt和已遍历到的连续1的数量n,遍历字符串时直接跳过字符0,仅对字符1进行处理;当检测到当前1右侧存在连续0时,标记为有效操作并直接跳过整段连续0,触发有效操作后将当前累计的1的数量n累加到总操作数cnt中;若遍历到后续的字符1,则递增n的计数,最终通过单次遍历完成所有有效操作的统计。

代码实现

cpp 复制代码
class Solution {
public:
    int maxOperations(string s) {
        int cnt = 0;
        int n = 1;
        for(int i = 0; i < s.size(); i++)
        {
            if(s[i] == '0')continue;

            bool flag = false;
            if(i < s.size() - 1 && s[i + 1] == '0')
            {
                s[i] = '0';
                flag = true;
                i++;
            }
            while(i < s.size() - 1 && s[i + 1] == '0')
            {
                i++;
            }
            if(flag)
            {
                cnt += n;
                s[i] = '1';
            }
            if(i < s.size() - 1 && s[i + 1] == '1')n++;
        }
        return cnt;
    }
};

复杂度分析

复杂度 量级
时间复杂度 O(n)
空间复杂度 O(1)

总结

总结

本题求解二进制字符串中1按规则右移的最大操作次数,采用线性遍历+计数统计的最优解法,仅需一次遍历字符串,通过累计已遍历的1的数量,在遇到1右侧的连续0时累加操作数,无需额外空间;算法时间复杂度为O(n)、空间复杂度为O(1),高效完成求解。

相关推荐
七颗糖很甜1 小时前
卫星通信遇到“太空天气”会怎样---电离层闪烁对卫星通信的影响
大数据·python·算法
fpcc1 小时前
跟我学C++中级篇—Linux文件读写的分析
linux·c++
小凡子空白在线学习1 小时前
工作拆分so总结
java·jvm·算法
88号技师1 小时前
2026年2月新锐一区SCI-完整家庭互动优化算法Undivided Family Interaction Algorithm-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
techdashen1 小时前
4 个字节拿到 root 权限:Linux 内核漏洞“Copy Fail“与 Cloudflare 的应急处置全记录
linux·网络·安全
南境十里·墨染春水1 小时前
linux学习进展 C语言连接mysql
linux·c语言·学习
李日灐1 小时前
【优选算法5】位运算经典算法面试题
后端·算法·面试·位运算
汉克老师1 小时前
GESP5级C++考试语法知识(十四、分治算法(一))
算法·归并排序·排序·分治算法·gesp5级·gesp五级
巨大八爪鱼1 小时前
瑞芯微RV1106通过MIPI CSI-2 D-PHY接口驱动OV5640摄像头并拍摄照片
linux·ov5640·mipi·v4l2·csi2-dphy