274. H 指数
给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。
根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且 至少 有 h 篇论文被引用次数大于等于 h 。如果 h 有多种可能的值,h 指数 是其中最大的那个。
示例 1:
输入:citations = [3,0,6,1,5]
输出:3
解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。
由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。
示例 2:
输入:citations = [1,3,1]
输出:1
提示:
n == citations.length
1 <= n <= 5000
0 <= citations[i] <= 1000
主要思路就是对数组进行一个排序,然后从前往后进行遍历,判断引用数是否大于等于剩余文章数,如果是,就结束for循环,并返回结果。
class Solution
{
public:
int hIndex(vector<int> &citations)
{
sort(citations.begin(), citations.end());
int h_index = citations.size();
for (int i = 0; i < citations.size(); i++)
{
h_index = citations.size() - i;
if (citations[i] >= h_index)
{
return h_index;
}
}
return 0;
}
};
135. 分发糖果
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例 1:
输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例 2:
输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
提示:
n == ratings.length
1
<
=
n
<
=
2
∗
1
0
4
1 <= n <= 2 * 10^4
1<=n<=2∗104
0
<
=
r
a
t
i
n
g
s
[
i
]
<
=
2
∗
1
0
4
0 <= ratings[i] <= 2 * 10^4
0<=ratings[i]<=2∗104
主要思路是:
① 首先给每个孩子分一个糖果。
② 按照得分值,对数组索引进行一个排序。
③ 从得分最低的孩子开始遍历,它的左相邻节点和右相邻节点应该都要满足条件2,利用这种局部性原理,进行扩散,按照步骤②中索引顺序遍历数组,最终得到总共需要的糖果数量。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 定义一个比较函数,根据原始vector的值来比较索引
bool compare(const std::pair<int, int> &a, const std::pair<int, int> &b)
{
return a.second < b.second;
}
std::vector<int> get_sorted_indices(const std::vector<int> &vec)
{
// 创建一个包含索引及其对应值的pair数组
std::vector<std::pair<int, int>> indexed_vec(vec.size());
for (size_t i = 0; i < vec.size(); ++i)
{
indexed_vec[i] = std::make_pair(i, vec[i]);
}
// 根据pair的值部分进行排序
std::sort(indexed_vec.begin(), indexed_vec.end(), compare);
// 提取排序后的索引
std::vector<int> sorted_indices(vec.size());
for (size_t i = 0; i < indexed_vec.size(); ++i)
{
sorted_indices[i] = indexed_vec[i].first;
}
return sorted_indices;
}
class Solution
{
public:
int candy(vector<int> &ratings)
{
int numAllCandy = ratings.size();
vector<int> numCandyEyeryone(ratings.size(), 1);
vector<int> sortIndex = get_sorted_indices(ratings);
for (int i = 0; i < sortIndex.size(); i++)
{
if ((sortIndex[i] - 1 >= 0 && ratings[sortIndex[i] - 1] > ratings[sortIndex[i]]))
{
if (numCandyEyeryone[sortIndex[i] - 1] <= numCandyEyeryone[sortIndex[i]])
{
numAllCandy += (numCandyEyeryone[sortIndex[i]] + 1) - numCandyEyeryone[sortIndex[i] - 1];
numCandyEyeryone[sortIndex[i] - 1] = numCandyEyeryone[sortIndex[i]] + 1;
}
}
if ((sortIndex[i] + 1 < ratings.size() && ratings[sortIndex[i] + 1] > ratings[sortIndex[i]]))
{
if (numCandyEyeryone[sortIndex[i] + 1] <= numCandyEyeryone[sortIndex[i]])
{
numAllCandy += (numCandyEyeryone[sortIndex[i]] + 1) - numCandyEyeryone[sortIndex[i] + 1];
numCandyEyeryone[sortIndex[i] + 1] = numCandyEyeryone[sortIndex[i]] + 1;
}
}
}
return numAllCandy;
}
};
int main()
{
vector<int> vec = {1, 3, 4};
Solution sol;
int res = sol.candy(vec);
cout << res << endl;
return 0;
}
58. 最后一个单词的长度
给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
示例 1:
输入:s = “Hello World”
输出:5
解释:最后一个单词是“World”,长度为 5。
示例 2:
输入:s = " fly me to the moon "
输出:4
解释:最后一个单词是“moon”,长度为 4。
示例 3:
输入:s = “luffy is still joyboy”
输出:6
解释:最后一个单词是长度为 6 的“joyboy”。
提示:
1
<
=
s
.
l
e
n
g
t
h
<
=
1
0
4
1 <= s.length <= 10^4
1<=s.length<=104
s 仅有英文字母和空格 ’ ’ 组成
s 中至少存在一个单词
#include <string>
#include <iostream>
using namespace std;
class Solution
{
public:
int lengthOfLastWord(string s)
{
int i;
for (i = s.size() - 1; i >= 0; i--)
{
if (s[i] != ' ')
{
break;
}
}
int numChar = 0;
for (; i >= 0; i--)
{
if (s[i] == ' ')
{
break;
}
else
{
numChar++;
}
}
return numChar;
}
};
int main()
{
string s = "this is a Model ";
Solution sol;
int res = sol.lengthOfLastWord(s);
cout << res << endl;
return 0;
}
151. 反转字符串中的单词
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = “the sky is blue”
输出:“blue is sky the”
示例 2:
输入:s = " hello world "
输出:“world hello”
解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:
输入:s = “a good example”
输出:“example good a”
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
提示:
1 <= s.length <= 104
s 包含英文大小写字母、数字和空格 ’ ’
s 中 至少存在一个 单词
从后向前遍历字符串,遍历完一个单词以后,正序插入到新的字符串中来:
#include <string>
#include <iostream>
using namespace std;
class Solution
{
public:
string reverseWords(string s)
{
int len = s.size();
string res(len, ' ');
int idx = 0;
for (int i = len - 1; i >= 0; i--)
{
while (i >= 0 && s[i] != ' ')
{
i--;
}
for (int j = i + 1; j < len && s[j] != ' '; j++)
{
if (idx > 0 && j == i + 1)
{
idx++;
}
res[idx] = s[j];
idx++;
}
}
res = res.substr(0, idx);
return res;
}
};
int main()
{
string s = " hello world ";
Solution sol;
string res = sol.reverseWords(s);
cout << res << endl;
}
进阶:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法。
class Solution {
public:
string reverseWords(string s) {
// 反转整个字符串
reverse(s.begin(), s.end());
int n = s.size();
int idx = 0;
for (int start = 0; start < n; ++start) {
if (s[start] != ' ') {
// 填一个空白字符然后将idx移动到下一个单词的开头位置
if (idx != 0) s[idx++] = ' ';
// 循环遍历至单词的末尾
int end = start;
while (end < n && s[end] != ' ') s[idx++] = s[end++];
// 反转整个单词
reverse(s.begin() + idx - (end - start), s.begin() + idx);
// 更新start,去找下一个单词
start = end;
}
}
s.erase(s.begin() + idx, s.end());
return s;
}
};