LeetCode 第23场双周赛

这次参加了LeeCode双周赛,差了一分钟拿到四个pass,最后排名是585/2044;

题目列表 得分
统计最大组的数目 3
构造 K 个回文字符串 5
圆和矩形是否有重叠 5
做菜顺序 6

1. 统计最大组的数目

题目描述

给你一个整数 n 。请你先求出从 1n 的每个整数 10 进制表示下的数位和(每一位上的数字相加),然后把数位和相等的数字放到同一个组中。

请你统计每个组中的数字数目,并返回数字数目并列最多的组有多少个。

示例 1:

输入:n = 13
输出:4
解释:总共有 9 个组,将 1 到 13 按数位求和后这些组分别是:
[1,10],[2,11],[3,12],[4,13],[5],[6],[7],[8],[9]。总共有 4 个组拥有的数字并列最多。

示例 2:

输入:n = 2
输出:2
解释:总共有 2 个大小为 1 的组 [1],[2]。

示例 3:

输入:n = 15
输出:6

示例 4:

输入:n = 24
输出:5

我的解法

class Solution {
public:
int countLargestGroup(int n) {
int Maxnum = -1;
int count = 0;
unordered_map<int,int> map;
for(int i = 1;i <= n;i++)
{
int sum = BitSum(i);
map[sum]++;
if(map[sum]>Maxnum)
{
Maxnum = map[sum];
count = 1;
}
else if(map[sum] == Maxnum)
{
count++;
}
}
return count;
}
int BitSum(int i)
{
int sum = 0;
while(i>0)
{
sum+=i%10;
i/=10;
}
return sum;
}
};

2. 构造K个回文字符串

题目描述

难度中等2

给你一个字符串 s 和一个整数 k 。请你用 s 字符串中 所有字符 构造 k 个非空 回文串

如果你可以用 s 中所有字符构造 k 个回文字符串,那么请你返回 True ,否则返回 False

示例 1:

输入:s = "annabelle", k = 2
输出:true
解释:可以用 s 中所有字符构造 2 个回文字符串。
一些可行的构造方案包括:"anna" + "elble","anbna" + "elle","anellena" + "b"

示例 2:

输入:s = "leetcode", k = 3
输出:false
解释:无法用 s 中所有字符构造 3 个回文串。

示例 3:

输入:s = "true", k = 4
输出:true
解释:唯一可行的方案是让 s 中每个字符单独构成一个字符串。

示例 4:

输入:s = "yzyzyzyzyzyzyzy", k = 2
输出:true
解释:你只需要将所有的 z 放在一个字符串中,所有的 y 放在另一个字符串中。那么两个字符串都是回文串。

示例 5:

输入:s = "cr", k = 7
输出:false
解释:我们没有足够的字符去构造 7 个回文串。

提示:

  • 1 <= s.length <= 10^5
  • s 中所有字符都是小写英文字母。
  • 1 <= k <= 10^5

我的解法

class Solution {
public:
bool canConstruct(string s, int k) {
if(k==0) return true;
int len = s.length();
unordered_map<char,int> map;
for(auto ch:s)
{
map[ch]++;
}
int i = 0;
unordered_map<char, int>::iterator iter;
for(iter = map.begin();iter!=map.end();iter++)
{
i+=iter->second%2;
}
cout<<i<<k<<len<<endl;
return i<=k&&(len-i)>=k-i;
}
};

3. 圆和矩形是否有重叠

题目描述

给你一个以 (radius, x_center, y_center) 表示的圆和一个与坐标轴平行的矩形 (x1, y1, x2, y2),其中 (x1, y1) 是矩形左下角的坐标,(x2, y2) 是右上角的坐标。

如果圆和矩形有重叠的部分,请你返回 True ,否则返回 False 。

换句话说,请你检测是否 存在 点 (xi, yi) ,它既在圆上也在矩形上(两者都包括点落在边界上的情况)。

示例 1:

img

输入:radius = 1, x_center = 0, y_center = 0, x1 = 1, y1 = -1, x2 = 3, y2 = 1
输出:true
解释:圆和矩形有公共点 (1,0)

示例 2:

img

输入:radius = 1, x_center = 0, y_center = 0, x1 = -1, y1 = 0, x2 = 0, y2 = 1
输出:true

示例 3:

img

输入:radius = 1, x_center = 1, y_center = 1, x1 = -3, y1 = -3, x2 = 3, y2 = 3
输出:true

示例 4:

输入:radius = 1, x_center = 1, y_center = 1, x1 = 1, y1 = -3, x2 = 2, y2 = -1
输出:false

提示:

  • 1 <= radius <= 2000
  • -10^4 <= x_center, y_center, x1, y1, x2, y2 <= 10^4
  • x1 < x2
  • y1 < y2

我的解法

思路

1. 先计算矩形中心,边长;

2. 把矩形中心,圆心投影到坐标轴上;

3. 计算矩形中心与圆心在坐标轴上的距离;

4. 判断,圆心超出矩形的距离是否小于圆的半径;

代码

class Solution {
public:
bool checkOverlap(int radius, int x_center, int y_center, int x1, int y1, int x2, int y2) {
double x= 0.5*(x1+x2),y=0.5*(y1+y2);
double lenx = x2-x1,leny = y2-y1;
double disx = abs(x_center-x);
double disy = abs(y_center-y);
double dis = max(disx-lenx/2,0.0)*max(disx-lenx/2,0.0)+max(disy-leny/2,0.0)*max(disy-leny/2,0.0);
return dis<=radius*radius;
}
};

其它解法

一个很经典的解法

class Solution{
public:
bool checkOverlap(int radius,int x_center,int y_center,int XI, Int y1, int X2, int y2){
int a =max(0, max(X1-x_center, x_center -X2));
int b= max(0, max(y1-y_center, y_center -y2));
return a*a+b*b<=radius*radius;
}
};

4. 做菜顺序

题目描述

一个厨师收集了他 n 道菜的满意程度 satisfaction ,这个厨师做出每道菜的时间都是 1 单位时间。

一道菜的 「喜爱时间」系数定义为烹饪这道菜以及之前每道菜所花费的时间乘以这道菜的满意程度,也就是 time[i]*satisfaction[i]

请你返回做完所有菜 「喜爱时间」总和的最大值为多少。

你可以按 任意 顺序安排做菜的顺序,你也可以选择放弃做某些菜来获得更大的总和。

示例 1:

输入:satisfaction = [-1,-8,0,5,-9]
输出:14
解释:去掉第二道和最后一道菜,最大的喜爱时间系数和为 (-1*1 + 0*2 + 5*3 = 14) 。每道菜都需要花费 1 单位时间完成。

示例 2:

输入:satisfaction = [4,3,2]
输出:20
解释:按照原来顺序相反的时间做菜 (2*1 + 3*2 + 4*3 = 20)

示例 3:

输入:satisfaction = [-1,-4,-5]
输出:0
解释:大家都不喜欢这些菜,所以不做任何菜可以获得最大的喜爱时间系数。

示例 4:

输入:satisfaction = [-2,5,-1,0,3,-3]
输出:35

提示:

  • n == satisfaction.length
  • 1 <= n <= 500
  • -10^3 <= satisfaction[i] <= 10^3

我的解法

思路

  1. 首先对满意度排序,满意度越大的菜方法放到后边越好
  2. 首先把满意度为正的菜的序号拿出来;
  3. 然后逐步放进满意度为负的菜;一直到总体满意度下降为止;
class Solution {
public:
int maxSatisfaction(vector<int>& satisfaction) {
sort(satisfaction.begin(),satisfaction.end());
int maxT = 0;
int pos = -1;
for(int i = 0;i<satisfaction.size();i++)
if(satisfaction[i]>0)
{
pos = i;
break;
}
if(pos<0)
return 0;
for(int j = pos;j>=0;j--)
{
int temp = Compute(satisfaction,j);
cout<<temp<<endl;
if(temp>maxT)
maxT = temp;
else
return maxT;
}
return maxT;
}

int Compute(vector<int>& satisfaction,int pos)
{
int sum=0;
int c = 0;
for(int i = pos;i<satisfaction.size();i++)
sum += satisfaction[i]* (++c);
return sum;
}
};
posted @ 2020-04-06 02:42  少年笔谈  阅读(189)  评论(0编辑  收藏  举报