leetcode第123场双周赛

100222. 三角形类型 II - 力扣(LeetCode)

给你一个下标从 0 开始长度为 3 的整数数组 nums ,需要用它们来构造三角形。

  • 如果一个三角形的所有边长度相等,那么这个三角形称为 equilateral
  • 如果一个三角形恰好有两条边长度相等,那么这个三角形称为 isosceles
  • 如果一个三角形三条边的长度互不相同,那么这个三角形称为 scalene

如果这个数组无法构成一个三角形,请你返回字符串 "none" ,否则返回一个字符串表示这个三角形的类型。

示例 1:

输入:nums = [3,3,3]
输出:"equilateral"
解释:由于三条边长度相等,所以可以构成一个等边三角形,返回 "equilateral" 。

示例 2:

输入:nums = [3,4,5]
输出:"scalene"
解释:
nums[0] + nums[1] = 3 + 4 = 7 ,大于 nums[2] = 5 。
nums[0] + nums[2] = 3 + 5 = 8 ,大于 nums[1] = 4 。
nums[1] + nums[2] = 4 + 5 = 9 ,大于 nums[0] = 3 。
由于任意两边纸盒都大于第三边,所以可以构成一个三角形。
因为三条边的长度互不相等,所以返回 "scalene" 。

提示:

  • nums.length == 3
  • 1 <= nums[i] <= 100
思路:

排序,然后比较,先判断能不能构成三角形,再判断各种情况

class Solution {
public:
    string triangleType(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int a = nums[0], b = nums[1], c = nums[2];
        if(a + b <= c)
            return "none";
        else if(a == b && a == c)
            return "equilateral";
        else if(a == b || a == c || b == c)
            return "isosceles";
        else
            return "scalene";
        
    }
};

100194. 人员站位的方案数 I - 力扣(LeetCode) &&100193. 人员站位的方案数 II - 力扣(LeetCode)

给你一个 n x 2 的二维数组 points ,它表示二维平面上的一些点坐标,其中 points[i] = [xi, yi]

我们定义 x 轴的正方向为 x 轴递增的方向),x 轴的负方向为 x 轴递减的方向)。类似的,我们定义 y 轴的正方向为 y 轴递增的方向),y 轴的负方向为 y 轴递减的方向)。

你需要安排这 n 个人的站位,这 n 个人中包括 liupengsay 和小羊肖恩 。你需要确保每个点处 恰好一个 人。同时,liupengsay 想跟小羊肖恩单独玩耍,所以 liupengsay 会以 liupengsay 的坐标为 左上角 ,小羊肖恩的坐标为 右下角 建立一个矩形的围栏(注意,围栏可能 包含任何区域,也就是说围栏可能是一条线段)。如果围栏的 内部 或者 边缘 上有任何其他人,liupengsay 都会难过。

请你在确保 liupengsay 不会 难过的前提下,返回 liupengsay 和小羊肖恩可以选择的 点对 数目。

注意,liupengsay 建立的围栏必须确保 liupengsay 的位置是矩形的左上角,小羊肖恩的位置是矩形的右下角。比方说,以 (1, 1)(1, 3)(3, 1)(3, 3) 为矩形的四个角,给定下图的两个输入,liupengsay 都不能建立围栏,原因如下:

  • 图一中,liupengsay 在 (3, 3) 且小羊肖恩在 (1, 1) ,liupengsay 的位置不是左上角且小羊肖恩的位置不是右下角。
  • 图二中,liupengsay 在 (1, 3) 且小羊肖恩在 (1, 1) ,小羊肖恩的位置不是在围栏的右下角。

在这里插入图片描述

示例 1:

https://assets.leetcode.com/uploads/2024/01/04/example1alicebob.png

输入:points = [[1,1],[2,2],[3,3]]
输出:0
解释:没有办法可以让 liupengsay 的围栏以 liupengsay 的位置为左上角且小羊肖恩的位置为右下角。所以我们返回 0 。

示例 2:

https://pic.leetcode.cn/1706880313-YelabI-example2.jpeg

输入:points = [[6,2],[4,4],[2,6]]
输出:2
解释:总共有 2 种方案安排 liupengsay 和小羊肖恩的位置,使得 liupengsay 不会难过:
- liupengsay 站在 (4, 4) ,小羊肖恩站在 (6, 2) 。
- liupengsay 站在 (2, 6) ,小羊肖恩站在 (4, 4) 。
不能安排 liupengsay 站在 (2, 6) 且小羊肖恩站在 (6, 2) ,因为站在 (4, 4) 的人处于围栏内。

示例 3:

https://pic.leetcode.cn/1706880311-mtPGYC-example3.jpeg

输入:points = [[3,1],[1,3],[1,1]]
输出:2
解释:总共有 2 种方案安排 liupengsay 和小羊肖恩的位置,使得 liupengsay 不会难过:
- liupengsay 站在 (1, 1) ,小羊肖恩站在 (3, 1) 。
- liupengsay 站在 (1, 3) ,小羊肖恩站在 (1, 1) 。
不能安排 liupengsay 站在 (1, 3) 且小羊肖恩站在 (3, 1) ,因为站在 (1, 1) 的人处于围栏内。
注意围栏是可以不包含任何面积的,上图中第一和第二个围栏都是合法的。

提示:

  • 2 <= n <= 50
  • points[i].length == 2
  • 0 <= points[i][0], points[i][1] <= 50
  • points[i] 点对两两不同。
思路:

这道题观察数据范围为 1000 1000 1000,所以可以考虑枚举 O ( n 2 ) O(n^2) O(n2)的时间复杂度可以过,但是枚举该怎么枚举呢,我们需要先排序,我们先固定第一个点为左上方的点,然后考虑右下方的点,所以我们可以按照横坐标从小到达排序,然后纵坐标从大到小排序,然后怎么得出答案呢,因为我们要考虑每个点之间是不是有点,所以还需要记录一个纵坐标的最大值,如果当前枚举到的这个值左边比最大的坐标还要大,就是处于更高的坐标,答案就可以增加了,并且最大的纵坐标更新成当前点的坐标

class Solution {
public:
    int numberOfPairs(vector<vector<int>>& points) {
        std::sort(points.begin(), points.end(), [](const auto& p, const auto& q) {
        return p[0] != q[0] ? p[0] < q[0] : p[1] > q[1];
        });
        int ans = 0, n = points.size();
        for(int i = 0; i < n; i ++)
        {
            int y0 = points[i][1];
            int max_y = INT_MIN;
            for(int j = i + 1; j < n; j ++)
            {
                int y = points[j][1];
                if(y <= y0 && y > max_y)
                {
                    max_y = y;
                    ans ++;
                }
            }
        }
        return ans;
    }
};

100183. 最大好子数组和 - 力扣(LeetCode)

给你一个长度为 n 的数组 nums 和一个 整数 k

如果 nums 的一个子数组中,第一个元素和最后一个元素 差的绝对值恰好k ,我们称这个子数组为 的。换句话说,如果子数组 nums[i..j] 满足 |nums[i] - nums[j]| == k ,那么它是一个好子数组。

请你返回 nums 子数组的 最大 和,如果没有好子数组,返回 0

示例 1:

输入:nums = [1,2,3,4,5,6], k = 1
输出:11
解释:好子数组中第一个元素和最后一个元素的差的绝对值必须为 1 。好子数组有 [1,2] ,[2,3] ,[3,4] ,[4,5] 和 [5,6] 。最大子数组和为 11 ,对应的子数组为 [5,6] 。

示例 2:

输入:nums = [-1,3,2,4,5], k = 3
输出:11
解释:好子数组中第一个元素和最后一个元素的差的绝对值必须为 3 。好子数组有 [-1,3,2] 和 [2,4,5] 。最大子数组和为 11 ,对应的子数组为 [2,4,5] 。

示例 3:

输入:nums = [-1,-2,-3,-4], k = 2
输出:-6
解释:好子数组中第一个元素和最后一个元素的差的绝对值必须为 2 。好子数组有 [-1,-2,-3] 和 [-2,-3,-4] 。最大子数组和为 -6 ,对应的子数组为 [-1,-2,-3] 。

提示:

  • 2 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • 1 <= k <= 109
思路:

这道题因为要求前缀和,所以肯定要用到前缀和,先简单复习一下前缀和,假设 s [ i ] s[i] s[i]为前缀和,我们定义 s [ 0 ] = 0 , s [ i + 1 ] s[0]=0, s[i + 1] s[0]=0,s[i+1]表示前i个元素的元素和,所以就可以得到 s [ i + 1 ] = s [ i ] + a [ i ] s[i + 1]=s[i] + a[i] s[i+1]=s[i]+a[i],假设求区间为 l e f t ∼ r i g h t left\sim right leftright的和,可以表示为 s [ r i g h t + 1 ] − s [ l e f t ] s[right + 1] - s[left] s[right+1]s[left],接下来我们需要对每一个元素进行枚举,假设枚举到 j j j这个元素,我们需要找到最小的 s [ i ] s[i] s[i]使得 a b s ( a [ j ] − a [ i ] ) = k abs(a[j] - a[i]) = k abs(a[j]a[i])=k,所以我们可以用哈希表来维护最小的 a [ i ] a[i] a[i]对应的 s [ i ] s[i] s[i],然后来枚举更新

class Solution {
public:
    long long maximumSubarraySum(vector<int>& nums, int k) {
        long long ans = LLONG_MIN, sum = 0;
        unordered_map<int, long long> min_s;
        for(int x : nums)
        {
            auto it = min_s.find(x + k);
            if(it != min_s.end())
            {
                ans = max(ans, sum + x - it->second);
            }
            it = min_s.find(x - k);
            if(it != min_s.end())
            {
                ans = max(ans, sum + x - it->second);
            }
            it = min_s.find(x);
            if(it == min_s.end() || sum < it->second)
                min_s[x] = sum;
            sum += x;
        }
        return ans == LLONG_MIN ? 0 : ans;
    }
};
  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值