LeetCode
截断句子
https://leetcode.cn/problems/truncate-sentence/description/
- 句子 是一个单词列表,列表中的单词之间用单个空格隔开,且不存在前导或尾随空格。每个单词仅由大小写英文字母组成(不含标点符号)。
- 例如,“Hello World”、“HELLO” 和 “hello world hello world” 都是句子。
给你一个句子 s 和一个整数 k ,请你将 s 截断 ,使截断后的句子仅含 前 k 个单词。返回 截断 s 后得到的句子 - 提示:
1 <= s.length <= 500
k 的取值范围是 [1, s 中单词的数目]
s 仅由大小写英文字母和空格组成
s 中的单词之间由单个空格隔开
不存在前导或尾随空格
代码实现:
class Solution {
public:
string truncateSentence(string s, int k) {
if(s.size() <1 || s.size() >500) {
return string();
}
string result;
int index = 0,index_s = 0;
while(index_s < s.size()) {
char data = s.at(index_s);
index_s += 1;
if(data == ' ') {
index += 1;
if(index == k) {
return result;
} else {
result.push_back(data);
}
} else {
result.push_back(data);
if(index_s == s.size()) {
assert(index+1 == k);
return result;
}
}
}
return result;
}
};
下一个更大元素 III
https://leetcode.cn/problems/next-greater-element-iii
- 给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n 中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1 。
- 注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1 。
思路:
- 将正整数转为一维数组先进行 评比找出第一个比之大的队列,然后评判是否越界,若没越界则进行还原整数返回。
代码实现:
-
int nextGreaterElement(int n) { if(n < 1 || n > (2147483648 -1)) return -1; vector<int> max_v = {2,1,4,7,4,8,3,6,4,7}; std::vector<int> vNum; while(n>0) { vNum.push_back(n%10); n = n / 10; } // 第一层遍历 for(int i=0;i<vNum.size();i++) { // 第二层遍历,找到比之大的,同时余下的进行排序 for(int j=0;j<i;j++) { if(vNum.at(j)>vNum.at(i)) { int tmp = vNum.at(j); vNum.at(j) = vNum.at(i); vNum.at(i) = tmp; sort(vNum.begin(),vNum.begin()+i,greater<int>()); if(vNum.size() == max_v.size()) { for(int i = vNum.size()-1;i>=0;i--) { int max_ds = max_v.at(vNum.size()-1-i); if(vNum.at(i) > max_ds) { return -1; } else if(vNum.at(i) < max_ds){ break; } } } long int result = 0,ssd = 1; for(int k = 0;k < vNum.size();k++) { result += vNum.at(k) * ssd; if(k+1 != vNum.size()) ssd = ssd * 10; } return result; } } } return -1; }
寻找两个整数序列的中位数
https://leetcode.cn/problems/median-of-two-sorted-arrays/description/
-
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
-
算法的时间复杂度应该为 O(log (m+n)) 。
思路:
- 这个题比较简单,先确定中位数下标(奇数还是偶数要注意),遍历两个序列,基于小值一次相加直到下标,然后计算得到。
double findMedianSortedArrays(const std::vector<int>& nums1,const std::vector<int>& nums2) {
const int size_total = nums1.size() + nums2.size();
std::deque<int> mind_index;
if(size_total % 2 == 1) {
mind_index.push_back((size_total+1)/2);
} else {
mind_index.push_back(size_total/2);
mind_index.push_back((size_total/2+1));
}
double result = 0; // 结果
int index_final = 0; // 已找个数
int nums1_index = 0,nums2_index = 0; // 1,2小标
while(nums1_index < nums1.size() || nums2_index < nums2.size()) {
int this_num = -1;
if(nums1_index < nums1.size() && nums2_index < nums2.size()) {
if(nums1.at(nums1_index) < nums2.at(nums2_index)) {
this_num = nums1.at(nums1_index++);
} else {
this_num = nums2.at(nums2_index++);
}
} else if(nums1_index < nums1.size() ) {
this_num = nums1.at(nums1_index++);
} else {
this_num = nums2.at(nums2_index++);
}
if( (++index_final) == mind_index.front()) {
result +=(this_num);
mind_index.pop_front();
}
if(mind_index.empty()) {
break;
}
}
if(size_total % 2 == 0) {
result /= 2;
}
return result;
}
对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。
思路:
- 一个递归,本题我使用了前中序遍历和后中序遍历进行比较,同时加了树深度,因为有个案例树深度不用还过不了。
bool isSymmetric(TreeNode* root) {
// 中序遍历改为前序遍历
if(root != nullptr) {
auto front_bl = FrontBL(root->left,1);
auto back_bl = BackBL(root->right,1);
if(front_bl.size() != back_bl.size()) {
return false;
}
std::cout<<"size:"<<front_bl.size()<<std::endl;
for(int i=0;i<front_bl.size();i++) {
if(front_bl.at(i).first != back_bl.at(i).first ||
front_bl.at(i).second != back_bl.at(i).second) {
return false;
}
}
}
return true;
}
std::vector<pair<int,int>> FrontBL(TreeNode* node,int depth) {
std::vector<pair<int,int>> result;
if(node != nullptr) {
auto left_result = FrontBL(node->left,depth+1);
auto right_result = FrontBL(node->right,depth+1);
result = left_result;
result.push_back(make_pair(node->val,depth));
result.insert(result.end(),right_result.begin(), right_result.end());
}else {
result.push_back(make_pair(-1,depth));
}
return result;
}
std::vector<pair<int,int>> BackBL(TreeNode* node,int depth) {
std::vector<pair<int,int>> result;
if(node != nullptr) {
auto left_result = BackBL(node->left,depth+1);
auto right_result = BackBL(node->right,depth+1);
result = right_result;
result.push_back(std::make_pair(node->val,depth));
result.insert(result.end(),left_result.begin(), left_result.end());
}else {
result.push_back(make_pair(-1,depth));
}
return result;
}
在每个树行中找最大值
https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/
- 给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
思路:
- 一个map记录该树每层最大值,然后将其最大值返回即可,树递归最简单
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int> result;
GetMaxDepth(root,0);
for(const auto& data: m_max_depth_) {
result.push_back(data.second);
}
return result;
}
std::map<int,int> m_max_depth_;
void GetMaxDepth(TreeNode* root,int depth) {
if(root == nullptr) {
return ;
}
if(m_max_depth_.count(depth)) {
if(m_max_depth_.at(depth) < root->val) {
m_max_depth_.at(depth) = root->val;
}
} else {
m_max_depth_.emplace(depth,root->val);
}
GetMaxDepth(root->left,depth+1);
GetMaxDepth(root->right,depth+1);
}
};
运动员和训练师的最大匹配数
- 给你一个下标从 0 开始的整数数组 players ,其中 players[i] 表示第 i 名运动员的 能力 值,同时给你一个下标从 0 开始的整数数组 trainers ,其中 trainers[j] 表示第 j 名训练师的 训练能力值 。
- 如果第 i 名运动员的能力值 小于等于 第 j 名训练师的能力值,那么第 i 名运动员可以 匹配 第 j 名训练师。除此以外,每名运动员至多可以匹配一位训练师,每位训练师最多可以匹配一位运动员。
- 请你返回满足上述要求 players 和 trainers 的 最大 匹配数。
Code:
class Solution {
public:
int matchPlayersAndTrainers(vector<int>& players, vector<int>& trainers) {
sort(players.begin(),players.end());
sort(trainers.begin(),trainers.end());
int result = 0;
int trainer_index = 0;
for(int i=0;i< players.size();i++) {
while(trainer_index < trainers.size()) {
if(players[i] <= trainers[trainer_index]) {
trainer_index ++;
result ++;
break;
}
trainer_index ++;
}
if(trainer_index >= trainers.size()) {
break;
}
}
return result;
}
};
牛客
比较版本号
牛客项目发布项目版本时会有版本号,比如1.02.11,2.14.4等等
- 现在给你2个版本号version1和version2,请你比较他们的大小
版本号是由修订号组成,修订号与修订号之间由一个"."连接。1个修订号可能有多位数字组成,修订可能包含前导0,且是合法的。例如,1.02.11,0.1,0.2都是合法的版本号
每个版本号至少包含1个修订号。
修订号从左到右编号,下标从0开始,最左边的修订号下标为0,下一个修订号下标为1,以此类推。
比较规则:
- 一. 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较忽略任何前导零后的整数值。比如"0.1"和"0.01"的版本号是相等的
- 二. 如果版本号没有指定某个下标处的修订号,则该修订号视为0。例如,“1.1"的版本号小于"1.1.1”。因为"1.1"的版本号相当于"1.1.0",第3位修订号的下标为0,小于1
- 三. version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0.
数据范围:
- 1 <= version1.length, version2.length <= 10001<=version1.length,version2.length<=1000
version1 和 version2 的修订号不会超过int的表达范围,即不超过 32 位整数 的范围
进阶: 空间复杂度 O(1)O(1) , 时间复杂度 O(n)O(n)
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 比较版本号
* @param version1 string字符串
* @param version2 string字符串
* @return int整型
*/
// write code here
int compare(std::string version1, std::string version2 ) {
if(version1.empty() || version2.empty()) {
return 0;
}
int v1_index = 0,v2_index = 0;
std::string v1_str,v2_str;
bool v1_dot=false,v2_dot=false;
while(1) {
if(!v1_dot && v1_index < version1.size()) {
if(version1[v1_index] == '.') {
v1_dot = true;
} else {
if(v1_str.empty() && version1[v1_index] == '0') {
} else {
v1_str.push_back(version1[v1_index]);
}
}
v1_index ++;
}
if(v1_index == version1.size()) {
v1_dot = true;
}
if(!v2_dot && v2_index < version2.size()) {
if(version2[v2_index] == '.') {
v2_dot = true;
} else {
if(v2_str.empty() && version2[v2_index]=='0'){
} else{
v2_str.push_back(version2[v2_index]);
}
}
v2_index++;
}
if(v2_index == version2.size()) {
v2_dot = true;
}
if(v1_dot && v2_dot) {
std::cout<<"dot1: "<<v1_str<<std::endl;
std::cout<<"dot2: "<<v2_str<<std::endl;
if(v1_str == v2_str) {
v1_str.clear();
v2_str.clear();
v1_dot = false;
v2_dot = false;
} else {
std::cout<<"no empty(): "<<std::endl;
if(v1_str.empty() && v2_str.empty()) {
v1_str.clear();
v2_str.clear();
v1_dot = false;
v2_dot = false;
}
if(!v1_str.empty() && !v2_str.empty()) {
if(v1_str == v2_str) {}
if(v1_str.size()> v2_str.size()) {return 1;}
if(v1_str.size() < v2_str.size()) {return -1;}
if(v1_str > v2_str){
return 1;
} else {
return -1;
}
} else if(v1_str.empty()) {
return -1;
} else {
return 1;
}
}
}
if(version1.size() == v1_index && version2.size() == v2_index ) {
break;
}
}
return 0;
}
};