9.12、 9.18 、9.19 Leetcode周赛题合集

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;
    }
};

差的绝对值为K的数目

给你一个整数数组 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;
    }    
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值