tips:这周打了leetcode的三把周赛(1次模拟)
结果很稳定的一如既往每次1到2道题
今天将简单写下我对这些题目的思路的代码
周赛签到题
给你一个下标从 0 开始的字符串 word 和一个字符 ch 。找出 ch 第一次出现的下标 i ,反转 word 中从下标 0 开始、直到下标 i 结束(含下标 i )的那段字符。如果 word 中不存在字符 ch ,则无需进行任何操作。
例如,如果 word = “abcdefd” 且 ch = “d” ,那么你应该 反转 从下标 0 开始、直到下标 3 结束(含下标 3 )。结果字符串将会是 “dcbaefd” 。
返回 结果字符串 。
附上链接:https://leetcode-cn.com/problems/reverse-prefix-of-word/
自从会了双指针,再也不用担心我不会担心字符串类、数组类的签到题了2333
题目很直接,就是反转字符串的前缀,所以就先循环遍历找到第一个字符,然后利用双指针进行第二次循环反转。
需要注意的地方就是,有可能不存在相关字符,所以在第一次循环遍历完后,可以对下标进行判断是否无相关字符,从而返回原字符串。
代码如下
class Solution {
public:
string reversePrefix(string word, char ch) {
// 双指针做法
// 声明左右指针(下标)
int left = 0, right = 0;
// 循环遍历到第一个相等字符
for(char w : word)
{
if(w == ch)
{
break;
}
right++;
}
// 特殊情况
if(right == word.length())
{
return word;
}
// 双下标循环移动,并且反转交换相关字符
while(left < right)
{
char temp = word[left];
word[left] = word[right];
word[right] = temp;
left++;
right--;
}
return word;
}
};
用一个下标从 0 开始的二维整数数组 rectangles 来表示 n 个矩形,其中 rectangles[i] = [widthi, heighti] 表示第 i 个矩形的宽度和高度。
如果两个矩形 i 和 j(i < j)的宽高比相同,则认为这两个矩形 可互换 。更规范的说法是,两个矩形满足 widthi/heighti == widthj/heightj(使用实数除法而非整数除法),则认为这两个矩形 可互换 。
计算并返回 rectangles 中有多少对 可互换 矩形。
附链接:
https://leetcode-cn.com/problems/number-of-pairs-of-interchangeable-rectangles/
自从会了自定义排序,很多碍于时间复杂度解不出来的题目都能轻松搞定
题目要求的是宽高比相同的矩形两两配对形成的矩形组数。
那我们不妨按照宽高比将矩形数组重新排序,这时候就用到了自定义排序,当然就是自定义cmp函数,然后用sort进行快速排序,然后再遍历一次,声明一个int变量num,如果宽高比相同,则num+1。当宽高比不同时,则以num计算组数,这就是高中数学中的求组合问题。组合数求完后,加在答案上,并将num赋0,继续遍历
代码如下
class Solution {
public:
static bool cmp(vector<int>&a, vector<int>&b)
{
double d_a = (double)(a[0] * 1.0f) / (a[1]);
double d_b = (double)(b[0] * 1.0f) / (b[1]);
return d_a < d_b;
}
long long compute(int num)
{
long long sum = 0;
while(num)
{
sum += num;
num--;
}
return sum;
}
long long interchangeableRectangles(vector<vector<int>>& rectangles) {
sort(rectangles.begin(), rectangles.end(), cmp);
int n = rectangles.size();
long long ans = 0;
int num = 0;
for(int i = 0; i < n - 1; i++)
{
if((double)(rectangles[i][0] * 1.0f) / (rectangles[i][1]) != (double)(rectangles[i + 1][0] * 1.0f) / (rectangles[i + 1][1]))
{
ans += compute(num);
num = 0;
}
else
{
num++;
}
}
ans += compute(num);
return ans;
}
};
给你一个整数数组 nums 和一个整数 k ,请你返回数对 (i, j) 的数目,满足 i < j 且 |nums[i] - nums[j]| == k 。
|x| 的值定义为:
如果 x >= 0 ,那么值为 x 。
如果 x < 0 ,那么值为 -x 。
链接:https://leetcode-cn.com/problems/count-number-of-pairs-with-absolute-difference-k/
相关示例
一般签到题都能直接暴力通过,这题就按照题目给的直接排序,然后循环遍历计算数组中元素差值是否为k即可
代码如下:
class Solution {
public:
int countKDifference(vector<int>& nums, int k) {
if(nums.size() == 1)
{
return 0;
}
sort(nums.begin(), nums.end());
int l = 0, r = 1, n = nums.size();
int ans = 0;
while(l < n -1)
{
for(r = l + 1; r < n; r++)
{
if(nums[r] - nums[l] == k)
{
ans++;
}
}
l++;
}
return ans;
}
};
又一道签到题
存在一种仅支持 4 种操作和 1 个变量 X 的编程语言:
++X 和 X++ 使变量 X 的值 加 1
–X 和 X-- 使变量 X 的值 减 1
最初,X 的值是 0
给你一个字符串数组 operations ,这是由操作组成的一个列表,返回执行所有操作后, X 的 最终值 。
链接:https://leetcode-cn.com/problems/final-value-of-variable-after-performing-operations/
class Solution {
public:
int finalValueAfterOperations(vector<string>& operations) {
int ans = 0;
for(string str : operations)
{
if(str == "X++" || str == "++X")
{
++ans;
}
else
{
--ans;
}
}
return ans;
}
};
数值美不美丽我不知道,反正我的心情给整的不美丽,差点做不出来
给你一个下标从 0 开始的整数数组 nums 。对于每个下标 i(1 <= i <= nums.length - 2),nums[i] 的 美丽值 等于:
2,对于所有 0 <= j < i 且 i < k <= nums.length - 1 ,满足 nums[j] < nums[i] < nums[k]
1,如果满足 nums[i - 1] < nums[i] < nums[i + 1] ,且不满足前面的条件
0,如果上述条件全部不满足
返回符合 1 <= i <= nums.length - 2 的所有 nums[i] 的 美丽值的总和 。
链接:https://leetcode-cn.com/problems/sum-of-beauty-in-the-array/
个人觉得是今天作者写的5道题最难的了
示例如下
这是今天周赛的第二题,而且直接的暴力模拟试过了,
结果是意料之中的runtimeerror
这里建议,读者在比赛中除了签到题,暴力模拟之类的时间复杂度过大的方法尽量不用,大概率是浪费时间的
按照定义计算美丽值,作者采用的是空间换时间的策略,自定义了两个数组,分别作为美丽值下标的左最大值数组和右最小值数组,则两个数组会存储下标左边和右边的最大值和最小值,然后再用一次遍历判断是否满足关系即可。
代码如下:
class Solution {
public:
int sumOfBeauties(vector<int>& nums) {
int n = nums.size();
vector<int> max_left(n - 2, 0), min_right(n - 2, 0);
int l = 0, r = n - 1;
while(l < n - 2)
{
if(l == 0)
{
max_left[l] = nums[0];
}
else
{
max_left[l] = max(max_left[l - 1], nums[l]);
}
l++;
}
while(r > 1)
{
if(r == n - 1)
{
min_right[r - 2] = nums[r];
}
else
{
min_right[r - 2] = min(nums[r], min_right[r -1]);
}
r--;
}
int ans = 0;
for(int i = 1; i < n - 1; i++)
{
if(nums[i] > max_left[i - 1] && nums[i] < min_right[i - 1])
{
ans +=2;
}
else if(nums[i] > nums[i - 1] && nums[i] < nums[i +1])
{
ans++;
}
}
return ans;
}
};