【leecode】【比赛】第20场双周赛

比赛地址:https://leetcode-cn.com/contest/biweekly-contest-20/

赛后总结

第一次参加leetcode的比赛,非常惨烈地只通过了一题(19min),打的太紧张,都无法正常思考了,打完就很难受。

做题过程反思:

第一题:简单题用时太久,因为害怕罚时而反复构造边界样例,实际上用口算估计一下即可。二进制操作不熟,要补上。(笔记跳转)

第二题:题目很长,读题没耐心,多处题意理解错误,最后也是因为没发现看错题目公式又怕罚时就放弃debug。编程出现低级错误。

第三题:和kickstart不同,leetcode没有单独小数据集,所以写暴力解法没用,应该直接写最优解。对循环的退出条件思路混乱。

不足和改进:

1.缺乏考场经验:做题很紧张。以后尽量每场比赛都参加,积累比赛经验。

2.编程低级错误:比如题目要求返回double,结果编程的时候忘了;比如把for当作while用。太紧张了会放大错误,平时加强练习。

3.语言特性掌握不熟练:比如容器的常见用法,数据类的函数。之后做个综合整理

4.容器的选择不熟练:之后单项练习结束后,做综合题时多思考下。

5.循环条件思路混乱:对于退出条件的设置思路比较乱,情况考虑不周全。想清楚循环变量代表的含义,平时练习一次想清楚,不要靠debug。

6.特殊样例考虑不全面:一般样例,边界样例;变量大小范围,运行时间范围。累加的变量记得用long long。

题目

四道题只做了前三题,第四题由于犯困的原因,这次先不看了下次再继续。

1.【easy】5323. Sort Integers by The Number of 1 Bits

Given an integer array arr. You have to sort the integers in the array in ascending order by the number of 1's in their binary representation and in case of two or more integers have the same number of 1's you have to sort them in ascending order.

Return the sorted array.

Example 1:

Input: arr = [0,1,2,3,4,5,6,7,8]
Output: [0,1,2,4,8,3,5,6,7]
Explantion: [0] is the only integer with 0 bits.
[1,2,4,8] all have 1 bit.
[3,5,6] have 2 bits.
[7] has 3 bits.
The sorted array by bits is [0,1,2,4,8,3,5,6,7]

Example 2:

Input: arr = [1024,512,256,128,64,32,16,8,4,2,1]
Output: [1,2,4,8,16,32,64,128,256,512,1024]
Explantion: All integers have 1 bit in the binary representation, you should just sort them in ascending order.

Example 3:

Input: arr = [10000,10000]
Output: [10000,10000]

Example 4:

Input: arr = [2,3,5,7,11,13,17,19]
Output: [2,3,5,17,7,11,13,19]

Example 5:

Input: arr = [10,100,1000,10000]
Output: [10,100,10000,1000]

Constraints:

  • 1 <= arr.length <= 500
  • 0 <= arr[i] <= 10^4

题目链接:https://leetcode-cn.com/problems/sort-integers-by-the-number-of-1-bits/

思路

没啥特别的,两个步骤:

1)计算二进制数上1的个数;

2)计算结果存储、排序、输出。

这题纠结了一下是用map还是priority_queue,最后为了排序选了pq,map没怎么用过,还不熟悉如何自定义排序函数。

二进制的操作是查来的,不太熟,这个盲点要补上。

class Solution {
public:
    struct cmp{
        bool operator()(pair<int,int>a, pair<int,int> b){
            if(a.first == b.first) return a.second>b.second;
            else return a.first>b.first;
        }
    };

    vector<int> sortByBits(vector<int>& arr) {
        vector<int> res;
        if(arr.size()<=0) return res;
        priority_queue<pair<int,int>, vector<pair<int,int>>,cmp > record;
        for(int i=0; i<arr.size(); ++i){
            int num = bitCount(arr[i]);
            record.push(make_pair(num, arr[i]));
        }
        while(!record.empty()){
            res.push_back(record.top().second);
            record.pop();
        }
        return res;
    }
    int bitCount(unsigned int n){
        unsigned int c =0 ;
        for (c =0; n; ++c){
            n &= (n -1) ; 
        }
        return c ;
    }
};

2.【medium】1357. Apply Discount Every n Orders

There is a sale in a supermarket, there will be a discount every n customer.
There are some products in the supermarket where the id of the i-th product is products[i] and the price per unit of this product is prices[i].
The system will count the number of customers and when the n-th customer arrive he/she will have a discount on the bill. (i.e if the cost is x the new cost is x - (discount * x) / 100). Then the system will start counting customers again.
The customer orders a certain amount of each product where product[i] is the id of the i-th product the customer ordered and amount[i] is the number of units the customer ordered of that product.

Implement the Cashier class:

  • Cashier(int n, int discount, int[] products, int[] prices) Initializes the object with n, the discount, the products and their prices.
  • double getBill(int[] product, int[] amount) returns the value of the bill and apply the discount if needed. Answers within 10^-5 of the actual value will be accepted as correct.

Example 1:

Input
["Cashier","getBill","getBill","getBill","getBill","getBill","getBill","getBill"]
[[3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,100]],[[1,2],[1,2]],[[3,7],[10,10]],[[1,2,3,4,5,6,7],[1,1,1,1,1,1,1]],[[4],[10]],[[7,3],[10,10]],[[7,5,3,1,6,4,2],[10,10,10,9,9,9,7]],[[2,3,5],[5,3,2]]]
Output
[null,500.0,4000.0,800.0,4000.0,4000.0,7350.0,2500.0]
Explanation
Cashier cashier = new Cashier(3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,100]);
cashier.getBill([1,2],[1,2]);                        // return 500.0, bill = 1 * 100 + 2 * 200 = 500.
cashier.getBill([3,7],[10,10]);                      // return 4000.0
cashier.getBill([1,2,3,4,5,6,7],[1,1,1,1,1,1,1]);    // return 800.0, The bill was 1600.0 but as this is the third customer, he has a discount of 50% which means his bill is only 1600 - 1600 * (50 / 100) = 800.
cashier.getBill([4],[10]);                           // return 4000.0
cashier.getBill([7,3],[10,10]);                      // return 4000.0
cashier.getBill([7,5,3,1,6,4,2],[10,10,10,9,9,9,7]); // return 7350.0, Bill was 14700.0 but as the system counted three more customers, he will have a 50% discount and the bill becomes 7350.0
cashier.getBill([2,3,5],[5,3,2]);                    // return 2500.0

Constraints:

  • 1 <= n <= 10^4
  • 0 <= discount <= 100
  • 1 <= products.length <= 200
  • 1 <= products[i] <= 200
  • There are not repeated elements in the array products.
  • prices.length == products.length
  • 1 <= prices[i] <= 1000
  • 1 <= product.length <= products.length
  • product[i] exists in products.
  • amount.length == product.length
  • 1 <= amount[i] <= 1000
  • At most 1000 calls will be made to getBill.
  • Answers within 10^-5 of the actual value will be accepted as correct.

题目链接:https://leetcode-cn.com/problems/apply-discount-every-n-orders/

思路

这道题,认真点,只有一个坑:读懂题。。。

其他没有任何难度,都是普通编程能力测试。

读题的坑:

1)products数组里值的含义:虽然题目样例里是从1开始递增的,但是实际使用时可以随便设;而顾客结账时传入的product数组的值就是从products数组里取的。这里需要通过值找到下标,再去prices中找价格。

2)计算折扣的方式:不是直接乘上折扣,而是减去折扣。

class Cashier {
    double dis;
    int m;
    int cur = 0;
    vector<int> pro;
    vector<int>pri;
public:
    Cashier(int n, int discount, vector<int>& products, vector<int>& prices) {
        dis = discount / 100.0; 
        m = n;
        pro = products;
        pri = prices;
    }
    
    double getBill(vector<int> product, vector<int> amount) {
        ++cur;
        if(product.size()<=0) return 0;
        long long sum = 0;
        double res = 0;
        for(int i=0; i<product.size(); ++i){
            sum = sum + (pri[idx(product[i])] * amount[i]);
        }
        if(cur == m) {
            res = sum - sum * dis;
            cur = 0;
        }else res = sum;
        return res;
    }
    int idx(int no){
        int i = 0;
        for(; i<pro.size();++i){
            if(pro[i]==no) break;
        }
        return i;
    }
};

/**
 * Your Cashier object will be instantiated and called as such:
 * Cashier* obj = new Cashier(n, discount, products, prices);
 * double param_1 = obj->getBill(product,amount);
 */

3.【medium】5325. Number of Substrings Containing All Three Characters

Given a string s consisting only of characters ab and c.

Return the number of substrings containing at least one occurrence of all these characters ab and c.

Example 1:

Input: s = "abcabc"
Output: 10
Explanation: The substrings containing at least one occurrence of the characters a, b and c are "abc", "abca", "abcab", "abcabc", "bca", "bcab", "bcabc", "cab", "cabc" and "abc" (again). 

Example 2:

Input: s = "aaacb"
Output: 3
Explanation: The substrings containing at least one occurrence of the characters a, b and c are "aaacb", "aacb" and "acb". 

Example 3:

Input: s = "abc"
Output: 1

Constraints:

  • 3 <= s.length <= 5 x 10^4
  • s only consists of ab or characters.

题目链接:https://leetcode-cn.com/problems/number-of-substrings-containing-all-three-characters/

思路

一看到题先想到的是暴力法:以每个节点作为子串的头,向后找符合条件的子串尾的个数。

当然暴力法肯定超时。说明方法还有提升空间,还有可压缩的步骤。

于是看到第2个样例,能够受到启发:只要末尾的"abc"子串ok了,那么包含这个子串 添加多少任意字符的上一级子串也都ok。

那么压缩点来了:暴力法中固定开头向后找尾的操作,只要找到了第一个尾,那么之后的元素就都是尾了。不用找,只用算啦。

class Solution {
public:
    int numberOfSubstrings(string s) {
        if(s.size()<3) return 0;
        long long num = 0;
        int arr[3] = {0,0,0};
        int i = 0,j = 0;
        ++arr[s[j]-'a'];
        while(true){
            if(j-i>=2 && arr[0]>0 && arr[1]>0 && arr[2]>0){
                num  = num + (s.size() - j);
                --arr[s[i++]-'a'];
            }
            else if(j<s.size()-1)  ++arr[s[++j]-'a'];
            else break;
        }
        return num;
    }
};
发布了126 篇原创文章 · 获赞 2 · 访问量 3733

猜你喜欢

转载自blog.csdn.net/lemonade13/article/details/104455373