1.树木规划
贪心的选最小的就是了。
class Solution {
public:
/**
* @param trees: the positions of trees.
* @param d: the minimum beautiful interval.
* @return: the minimum number of trees to remove to make trees beautiful.
*/
int treePlanning(vector<int> &trees, int d) {
// write your code here.
int ans = 1,pre = trees[0];
for(int i = 1;i < trees.size();++i){
if(trees[i]-pre>=d){
++ans;
pre = trees[i];
}
}
return trees.size()-ans;
}
};
2.正三角形拼接
① 如果有三个一样的,那么为 0 ,
② 不满足①,如果有两个一样的,但不是最大值,那么为1
③ 不满足①②,如果有某个数的倍数的话,也为1(坑点)
④ 不满足①②③ 为0.
class Solution {
public:
/**
* @param lengths: the lengths of sticks at the beginning.
* @return: return the minimum number of cuts.
*/
int makeEquilateralTriangle(vector<int> &lengths) {
// write your code here.
map<int,int>vis;
bool f = 0;
int maxx = 0;
for(int i = 0;i < lengths.size();++i){
vis[lengths[i]]++;
maxx = max(maxx,lengths[i]);
if(vis[lengths[i]]>=3)f = 1;
}
if(f)return 0;
int res = -1,ans = 2;
for(int i = 0;i < lengths.size();++i){
for(int j = 0;j < lengths.size();++j){
if(i==j)continue;
if(lengths[j]%lengths[i]==0)ans = 1;
}
}
for(auto it:vis){
if(it.second>=2){
res = it.first;
if(res!=maxx)ans = min(ans,1);
break;
}
}
return ans;
}
};
3.大楼间穿梭
用单调栈维护右边第一个比它的数,或者用数据结构也可。
然后处理出来之后典型的dp
class Solution {
public:
/**
* @param heights: the heights of buildings.
* @param k: the vision.
* @param x: the energy to spend of the first action.
* @param y: the energy to spend of the second action.
* @return: the minimal energy to spend.
*/
#define ll long long
#define man 200000
ll dp[man],pos[man];
long long shuttleInBuildings(vector<int> &heights, int k, int x, int y) {
// write your code here.
stack<int>sta;
for(int i = 0;i < heights.size();++i){
dp[i] = (long long)1e18;
pos[i] = heights.size() + 1;
}
for(int i = 0;i < heights.size();++i){
while(sta.size()&&heights[sta.top()]<=heights[i]){
pos[sta.top()] = i;
sta.pop();
}
sta.push(i);
}
dp[0] = 0;
for(int i = 0;i < heights.size();++i){
if(i+1<heights.size())dp[i+1] = min(dp[i+1],dp[i]+y);
if(i+2<heights.size())dp[i+2] = min(dp[i+2],dp[i]+y);
if(pos[i]<heights.size()&&pos[i]-i<=k)dp[pos[i]] = min(dp[pos[i]],dp[i]+x);
}
return dp[heights.size()-1];
}
};
4.对称前后缀
如果枚举每个子串 ,然后判断的话那么复杂度就是
,我们需要一种方法,可以利用之前处理的信息,那就是枚举回文串的中点(奇数串+偶数串)。
注意:题目说的最长对称前后缀长度一开始理解错了,对于
这个长度是 2 ,不是 1,而 bacb 就是
。
class Solution {
public:
/**
* @param s: a string.
* @return: return the values of all the intervals.
*/
long long suffixQuery(string &s) {
// write your code here
long long res = 0;
for(int i = 0;i < s.size();++i){
long long sum = 0;
int id = 0;
bool f = 1;
while(i-id>=0&&i+id<s.size()){
if(s[i-id]==s[i+id])++sum;
else sum = 0,f = 0;
if(f)res += sum * 2 - 1;
else res += sum;
++id;
}
f = 1;
sum = 0;
id = 1;
while(i-id>=0&&i+id-1<s.size()){
if(s[i+id-1]==s[i-id])++sum;
else sum = 0,f = 0;
++id;
if(f)res += 2*sum;
else res += sum;
}
}
return res;
}
};