首页 > 其他分享 >1326. 灌溉花园的最少水龙头数目

1326. 灌溉花园的最少水龙头数目

时间:2023-04-08 17:55:27浏览次数:56  
标签:1326 int ranges 最少 rg 端点 水龙头 last

题目链接:1326. 灌溉花园的最少水龙头数目

方法:贪心

解题思路

每次到达端点l时,寻找在此处能够到达的最远右端点;
思路一: 先对每个水龙头能够覆盖的 \([l, r]\) 构成的数组 \(rg\) 按照 \(l\) 进行从小到大排序,然后遍历右端点 \(r=[0, n]\),对于当前 \(r\),在 \(rg\) 中找其能够到达的下一个最右端点,若不存在,则返回 \(-1\),否则继续遍历右端点,最后输出 \(cnt\);
思路二: 对 \(ranges\) 数组进行预处理,创建 \(last\) 数组,\(last[i]\) 表示从 \(i\) 处开始能够覆盖的最远右端点。然后遍历右端点 \(r=[0, n]\),对于当前 \(r\),在 \(last\) 中找其能够到达的下一个最右端点,若不存在,则返回 \(-1\),否则继续遍历右端点,最后输出 \(cnt\);

代码一

class Solution {
public:
    int minTaps(int n, vector<int>& ranges) {
        vector<pair<int, int>> rg(n + 1); // rg[i]表示i处水龙头的灌溉区域[first, second]
        for (int i = 0; i < ranges.size(); i ++ ) {
            rg[i].first = i - ranges[i];
            rg[i].second = i + ranges[i];
        }
        sort(rg.begin(), rg.end()); // 默认先根据rg[i].first从小到大排序
        int r = 0, i = 0;
        int cnt = 0;
        while (r < n) {
            int mx = -1;
            while (i < rg.size() && rg[i].first <= r) { // 当前右端点能覆盖i水龙头的左端点
                mx = max(mx, rg[i].second);
                i ++ ;
            }
            if (mx == -1) return -1; // 没找到比当前右端点更远的右端点
            r = mx;
            cnt ++ ;
        }
        return cnt;
    }
};

复杂度分析

时间复杂度:\(O(nlogn)\);
空间读杂度:\(O(n)\)。

代码二

class Solution {
public:
    int minTaps(int n, vector<int>& ranges) {
        vector<int> last(n + 1);
        for (int i = 0; i < ranges.size(); i ++ ) {
            int l = max(0, i - ranges[i]), r = min(n, i + ranges[i]); // 左端点小于0 || 右端点大于n 无意义
            last[l] = max(last[l], r);
        }
        int cnt = 0, r = 0, i = 0;
        while (r < n) {
            int mx = -1;
            while (i < n && r >= i) { // 当前右端点能覆盖i处
                if (last[i] > r) mx = max(mx, last[i]); 
                i ++ ; // 若last[i] <= r此时没有超过当前右端点,直接 i ++
            }
            if (mx == -1) return -1; // 没找到比当前右端点更远的右端点
            cnt ++ ;
            r = mx;
        }
        return cnt;
    }
};

复杂度分析

时间复杂度:\(O(n)\);
空间读杂度:\(O(n)\)。

标签:1326,int,ranges,最少,rg,端点,水龙头,last
From: https://www.cnblogs.com/lxycoding/p/17298919.html

相关文章

  • 1210. 穿过迷宫的最少移动次数
    题目链接:1210.穿过迷宫的最少移动次数参考:还在if-else?一个循环处理六种移动!代码classSolution{private:staticconstexprintmov[3][3]={{1,0,0},{0,1,0},{0,0,1}};//下、右、旋转public:intminimumMoves(vector<vector<int>>&grid){......
  • Transferwise:以最快的速度最少的费用为你提供国际转账服务
    是否觉得国际转账银行有时高得离谱,大概这个地球上没有一个觉得银行的货币兑换收费低的吧,除非你在银行工作。但是,创业公司Transferwise就能将这个转账费用降到很低。产品公......
  • 6357.使数组元素全部相等的最少操作次数-338
    使数组元素全部相等的最小操作次数给你一个正整数数组 nums 。同时给你一个长度为m 的整数数组 queries 。第i 个查询中,你需要将nums 中所有元素变成 queries......
  • 20201326_exp2_后门原理与实践_实验报告
    20201326EXP2-后门原理与实践一、实验基础实验目的本次实验需要我们掌握后门的基础知识,学习使用nc实现Windows,Linux之间的后门连接,学习使用Metaspolit的msfvenom指令......
  • 华为OD机试 最少停车数
    本期题目:最少停车数......
  • 1541. 平衡括号字符串的最少插入次数
    给你一个括号字符串 s ,它只包含字符 '('和 ')' 。一个括号字符串被称为平衡的当它满足:任何左括号 '(' 必须对应两个连续的右括号 '))' 。左括号 '(' 必须在......
  • 6318.完成所有任务的最少时间-336
    完成所有任务的最少时间你有一台电脑,它可以同时 运行无数个任务。给你一个二维整数数组 tasks ,其中 tasks[i]=[starti,endi,durationi] 表示第 i 个任务需要......
  • 力扣简2379 得到第k个黑块的最少涂色次数
    20230310每日一题滑动窗口题 classSolution{publicintminimumRecolors(Stringblocks,intk){intres=Integer.MAX_VALUE,len=blocks.length();......
  • 2379. 得到 K 个黑块的最少涂色次数
    给你一个长度为n 下标从0 开始的字符串 blocks ,blocks[i] 要么是 'W' 要么是 'B' ,表示第 i 块的颜色。字符 'W'和 'B' 分别表示白色和黑色。给你一个整......
  • 力扣---2379. 得到 K 个黑块的最少涂色次数
    给你一个长度为n下标从0开始的字符串blocks,blocks[i]要么是'W'要么是'B',表示第i块的颜色。字符'W'和'B'分别表示白色和黑色。给你一个整数k,表示想要连......