#第189场周赛题解

A题:

给你两个整数数组 startTime(开始时间)和 endTime(结束时间),并指定一个整数 queryTime 作为查询时间。

已知,第 i 名学生在 startTime[i] 时开始写作业并于endTime[i]时完成作业。

请返回在查询时间 queryTime 时正在做作业的学生人数。形式上,返回能够使 queryTime 处于区间 [startTime[i], endTime[i]](含)的学生人数。

示例 1:

输入:startTime = [1,2,3], endTime = [3,2,7], queryTime = 4
输出:1
解释:一共有 3 名学生。
第一名学生在时间 1 开始写作业,并于时间 3 完成作业,在时间 4 没有处于做作业的状态。
第二名学生在时间 2 开始写作业,并于时间 2 完成作业,在时间 4 没有处于做作业的状态。
第二名学生在时间 3 开始写作业,预计于时间 7 完成作业,这是是唯一一名在时间 4 时正在做作业的学生。

示例 2:

输入:startTime = [4], endTime = [4], queryTime = 4
输出:1
解释:在查询时间只有一名学生在做作业。

示例 3:

输入:startTime = [4], endTime = [4], queryTime = 5
输出:0

示例 4:

输入:startTime = [1,1,1,1], endTime = [1,3,2,4], queryTime = 7
输出:0

示例 5:

输入:startTime = [9,8,7,6,5,4,3,2,1], endTime = [10,10,10,10,10,10,10,10,10], queryTime = 5
输出:5

提示:

  • startTime.length == endTime.length
  • 1 <= startTime.length <= 100
  • 1 <= startTime[i] <= endTime[i] <= 1000
  • 1 <= queryTime <= 1000

思路:

枚举区间

class Solution {
public:
    int busyStudent(vector<int>& a, vector<int>& b, int c) {
        int len = a.size();
        int ans = 0;
        for(int i = 0;i < len;++i){
            if(a[i]<=c && b[i] >= c)ans++;
        }
        return ans;
    }
};


B题:

「句子」是一个用空格分隔单词的字符串。给你一个满足下述格式的句子 text :

  • 句子的首字母大写
  • text 中的每个单词都用单个空格分隔。

请你重新排列 text 中的单词,使所有单词按其长度的升序排列。如果两个单词的长度相同,则保留其在原句子中的相对顺序。

请同样按上述格式返回新的句子。

示例 1:

输入:text = "Leetcode is cool"
输出:"Is cool leetcode"
解释:句子中共有 3 个单词,长度为 8 的 "Leetcode" ,长度为 2 的 "is" 以及长度为 4 的 "cool" 。
输出需要按单词的长度升序排列,新句子中的第一个单词首字母需要大写。

示例 2:

输入:text = "Keep calm and code on"
输出:"On and keep calm code"
解释:输出的排序情况如下:
"On" 2 个字母。
"and" 3 个字母。
"keep" 4 个字母,因为存在长度相同的其他单词,所以它们之间需要保留在原句子中的相对顺序。
"calm" 4 个字母。
"code" 4 个字母。

示例 3:

输入:text = "To be or not to be"
输出:"To be or to be not"

提示:

  • text 以大写字母开头,然后包含若干小写字母以及单词间的单个空格。
  • 1 <= text.length <= 10^5

思路:

字符串操作 + 排序

重要的点是取出单词 句子后补空格 或者 使用stringstream流

//补空格法、双百
vector<string>words;
vector<int>idx , len;

inline bool cmp(int a,int b){
    if(len[a] != len[b])return len[a] < len[b];
    return a < b;
}

class Solution {
public:
    string arrangeWords(string text) {
        words.clear();idx.clear();len.clear();

        string cur = "";
        text += " ";//补空位
        for(auto c : text){
            if( c == ' '){
                words.push_back(cur);
                cur = "";
            }

            else{
                if(c >= 'A' &&  c <= 'Z') c = c - 'A' + 'a';
                cur += c;
            }
        }

        int n = words.size();
        for(int i = 0;i < n;++i){
            idx.push_back(i);
            len.push_back(words[i].length());
        }

        sort(idx.begin(),idx.end(),cmp);

        string ans = "";
        for(int i = 0;i < n;++i){
            if(i > 0)ans += " ";
            ans += words[idx[i]];
        }
        ans[0] = ans[0] -  'a' + 'A';

        return ans;
    }
};

C题:

给你一个数组 favoriteCompanies ,其中 favoriteCompanies[i] 是第 i 名用户收藏的公司清单(下标从 0 开始)。

请找出不是其他任何人收藏的公司清单的子集的收藏清单,并返回该清单下标。下标需要按升序排列。

示例 1:

输入:favoriteCompanies = [["leetcode","google","facebook"],["google","microsoft"],["google","facebook"],["google"],["amazon"]]
输出:[0,1,4] 
解释:
favoriteCompanies[2]=["google","facebook"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 的子集。
favoriteCompanies[3]=["google"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 和 favoriteCompanies[1]=["google","microsoft"] 的子集。
其余的收藏清单均不是其他任何人收藏的公司清单的子集,因此,答案为 [0,1,4] 。

示例 2:

输入:favoriteCompanies = [["leetcode","google","facebook"],["leetcode","amazon"],["facebook","google"]]
输出:[0,1] 
解释:favoriteCompanies[2]=["facebook","google"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 的子集,因此,答案为 [0,1] 。

示例 3:

输入:favoriteCompanies = [["leetcode"],["google"],["facebook"],["amazon"]]
输出:[0,1,2,3]

提示:

  • 1 <= favoriteCompanies.length <= 100
  • 1 <= favoriteCompanies[i].length <= 500
  • 1 <= favoriteCompanies[i][j].length <= 20
  • favoriteCompanies[i] 中的所有字符串 各不相同 。
    用户收藏的公司清单也 各不相同 ,也就是说,即便我们按字母顺序排序每个清单, favoriteCompanies[i] != favoriteCompanies[j] 仍然成立。
  • 所有字符串仅包含小写英文字母。

思路:

暴力判断

class Solution {
public:
    vector<int> peopleIndexes(vector<vector<string>>& fC) {
        int n = fC.size();
        vector<int>v;
        for(int i = 0;i < n; ++i) sort(fC[i].begin(),fC[i].end());

        for(int i = 0;i < n; ++i){
            bool flag = true;
            for(int k = 0;k < n && flag; ++k){
                if(i == k)continue;
                int cur = 0,m = fC[i].size();
                for(int j = 0, lim = fC[k].size(); j < lim && cur < m ;++j){
                    if(fC[i][cur] == fC[k][j]) ++cur;
                }
                if(cur >= m)flag = false;
            }
            if(flag)v.push_back(i);
        }
        return v;
    }
};

D题:

墙壁上挂着一个圆形的飞镖靶。现在请你蒙着眼睛向靶上投掷飞镖。

投掷到墙上的飞镖用二维平面上的点坐标数组表示。飞镖靶的半径为 r 。

请返回能够落在 任意 半径为 r 的圆形靶内或靶上的最大飞镖数。

没做出来。。。看题解说万能的知乎有解答公式还没去看

先copy下暴力枚举的方法吧

慢慢理解

struct Point {
	double x, y;
	Point() {}
	Point(double tx, double ty) { x = tx; y = ty; }
};
const double eps = 1e-10;
class Solution {
public:
    double dist(Point p1,Point p2) {
	    return sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2));
    }

    Point GetCircleCenter(Point p1, Point p2, double r) {
	    Point mid = Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
	    double angle = atan2(p1.x - p2.x, p2.y - p1.y);
	    double d = sqrt(r*r - pow(dist(p1, mid), 2));
	    return Point(mid.x + d*cos(angle), mid.y + d*sin(angle));
    }
    
    int numPoints(vector<vector<int>>& points, int r) {
        int ans = 1;
        for (int i = 0; i < points.size(); ++i) {
            for (int j = i + 1; j < points.size(); ++j) {
                if(dist(Point(1.0 * points[i][0], 1.0 * points[i][1]), 
                        Point(1.0 * points[j][0], 1.0 * points[j][1])) > 2.0*r)
                    continue;
                Point center = GetCircleCenter(
                               Point(1.0 * points[i][0], 1.0 * points[i][1]), 
                               Point(1.0 * points[j][0], 1.0 * points[j][1]), 
                               1.0 * r
                               );
                int cnt = 0;
				for(int k = 0; k < points.size(); ++k)
                    if(dist(center, Point(1.0 * points[k][0], 1.0 * points[k][1])) 
                       < 1.0*r + eps) 
                        cnt++;
				ans = max(ans,cnt);
            } 
        }
        return ans;
    }
};
原文地址:https://www.cnblogs.com/RioTian/p/12904904.html