Leetcode 将 x 减到 0 的最小操作数

1. 题目链接:将 x 减到 0 的最小操作数 (medium)

2. 题目描述:

3. 解法(滑动窗口):

算法思路:

题目要求的是数组「左端+右端」两段连续的、和为x 的最短数组,信息量稍微多一些,不易理清

思路;我们可以转化成求数组内一段连续的、和为sum(nums) - x 的最长数组。此时,就是熟

悉的「滑动窗口」问题了。

算法流程:

a. 转化问题:求 target = sum(nums) - x 。如果 target < 0 ,问题无解;
b. 初始化左右指针 l = 0 , r = 0 (滑动窗口区间表示为 [l, r) ,左右区间是否开闭很重要,必须设定与代码一致),记录当前滑动窗口内数组和的变量 sum = 0 ,记录当前满足条件数组的最大区间长度 maxLen = -1 ;
c. 当r 小于等于数组长度时,一直循环:

i. 如果 sum < target ,右移右指针,直至变量和大于等于 target ,或右指针已经移到头;

ii. 如果 sum > target ,右移左指针,直至变量和小于等于 target ,或左指针已经移到头;

iii. 如果经过前两步的左右移动使得 sum == target ,维护满足条件数组的最大长度,并让 下个元素进入窗口;
d. 循环结束后,如果 maxLen 的值有意义,则计算结果返回;否则,返回-1 。

C++ 算法代码:

cpp 复制代码
class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int total = accumulate(nums.begin(), nums.end(), 0);
        int target = total - x;
        if (target < 0) {
            return -1;
        }

        int left = 0;
        int right = 0;
        int len = -1;
        int sum = 0;

        int n = nums.size();

        for (right = 0; right < n; right++) {
            sum += nums[right];
            while (sum > target) {
                sum -= nums[left++];
            }
            if (sum == target)
                len = (right - left + 1) > len ? (right - left + 1) : len;
        }
        return len == -1 ? len : n - len;
    }
};

C++ 代码结果:

Java 算法代码:

java 复制代码
class Solution
{
    public int minOperations(int[] nums, int x)
    {
        int sum = 0;
        for(int a : nums) sum += a;
        int target = sum - x;
        // 处理细节
        if(target < 0) return -1;
        int ret = -1;
        for(int left = 0, right = 0, tmp = 0; right < nums.length; right++)
        {
            tmp += nums[right]; // 进窗口
            while(tmp > target) // 判断
            tmp -= nums[left++]; // 出窗口
            if(tmp == target)
                ret = Math.max(ret, right - left + 1); // 更新结果
        }
        if(ret == -1) return ret;
        else return nums.length - ret;
    }
}

Java 运行结果:

相关推荐
CS创新实验室1 天前
从顺序表到动态数组:数据结构的永恒基石与现代语言的优雅封装
数据结构·算法
8Qi81 天前
LeetCode 23. 合并 K 个升序链表 —— 小顶堆(PriorityQueue)
数据结构·算法·leetcode·链表·
QiLinkOS1 天前
《打破“用爱发电”:一种基于 Gitee 与时间戳的开源权益分配机制探索》
c语言·数据结构·c++·科技·算法·gitee·开源
Boom_Shu1 天前
长方形的关系
数据结构·c++·算法
Lsk_Smion1 天前
力扣实训 _ [543].二叉树的直径 _ [23].合并K个升序列表
数据结构·算法·leetcode
ID_180079054731 天前
淘宝商品详情数据接口深度解析:架构、鉴权、数据结构与实战
数据结构·架构
散峰而望1 天前
【算法练习】算法练习精选:陶陶摘苹果(基础+升级)、Music Notes、字串变换,你能AC几道?
数据结构·c++·算法·leetcode·贪心算法·github·动态规划
凤凰院凶涛QAQ1 天前
《Java版数据结构 & 集合类剖析》集合框架的封装设计与顺序表:“从 Iterable 到 ArrayList:集合框架的‘职业树“
java·开发语言·数据结构
8Qi81 天前
LeetCode 148. 排序链表 —— 解法一:自顶向下递归(分治 + 归并)
数据结构·算法·leetcode·链表·递归·分治·归并
8Qi81 天前
LeetCode 148. 排序链表 —— 解法二:自底向上归并(迭代,O(1) 空间)
数据结构·算法·leetcode·链表·归并·迭代