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:
输入:points = [[1,1],[2,2],[3,3]]
输出:0
解释:没有办法可以让 liupengsay 的围栏以 liupengsay 的位置为左上角且小羊肖恩的位置为右下角。所以我们返回 0 。
示例 2:
输入: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:
输入: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 left∼right的和,可以表示为 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;
}
};