最长回文子串(简单)(双指针,dp,马拉车)
链接:https://www.nowcoder.com/questionTerminal/b4525d1d84934cf280439aeecc36f4af
来源:牛客网
对于长度为n的一个字符串A(仅包含数字,大小写英文字母),请设计一个高效算法,计算其中最长回文子串的长度。
数据范围: 1≤n≤10001 \le n \le 10001≤n≤1000
要求:空间复杂度 O(1)O(1)O(1),时间复杂度 O(n2)O(n^2)O(n2)
进阶: 空间复杂度 O(n)O(n)O(n),时间复杂度 O(n)O(n)O(n)
示例1
输入
"ababc"
输出
3
说明
最长的回文子串为"aba"与"bab",长度都为3
示例2
输入
"abbba"
输出
5
示例3
输入
"b"
输出
1
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param A string字符串
* @return int整型
*/
int func(string str,int i)
{
int left=i;
int right=i;
int ret1=0;
while(left>=0&&right<str.size()&&str[left]==str[right])
{
left--;
right++;
}
ret1=right-left-1;
int ret2=0;
left=i-1;
right=i;
if(str[left]==str[right])
while(left>=0&&right<str.size()&&str[left]==str[right])
{
left--;
right++;
}
ret2=right-left-1;
return max(ret1,ret2);
}
int getLongestPalindrome(string str) {
int n=str.size();
int sum=0;
for(int i=0;i<n;i++)
{
sum=max(func(str,i),sum);
}
return sum;
}
};
DP30 买卖股票的最好时机(一)(简单)(贪心,dp)
买卖股票的最好时机(一)_牛客题霸_牛客网 (nowcoder.com)
描述
假设你有一个数组prices,长度为n,其中prices[i]是股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1.你可以买入一次股票和卖出一次股票,并非每天都可以买入或卖出一次,总共只能买入和卖出一次,且买入必须在卖出的前面的某一天
2.如果不能获取到任何利润,请返回0
3.假设买入卖出均无手续费
数据范围: 0≤𝑛≤105,0≤𝑣𝑎𝑙≤1040≤n≤105,0≤val≤104
输入描述:
第一行输入一个正整数 n 表示数组的长度
第二行输入 n 个正整数,表示股票在第 i 天的价格
输出描述:
输出只买卖一次的最高收益
示例1
输入:
7
8 9 2 5 4 7 1
复制
输出:
5
复制
说明:
在第3天(股票价格 = 2)的时候买入,在第6天(股票价格 = 7)的时候卖出,最大利润 = 7-2 = 5 ,不能选择在第2天买入,第3天卖出,这样就亏损7了;同时,你也不能在买入前卖出股票。
示例2
输入:
3
2 4 1
复制
输出:
2
复制
示例3
输入:
3
3 2 1
复制
输出:
0
#include <iostream>
using namespace std;
int prices[100010];
int main() {
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>prices[i];
}
int dp1[100010];
int dp2[100010];
dp1[0]=prices[0];
dp2[0]=0;
int ret=0;
for(int i=1;i<n;i++)
{
dp1[i]=min(dp1[i-1],prices[i]);
dp2[i]=prices[i]-dp1[i-1];
ret=max(ret,dp2[i]);
}
cout<< ret;
return 0;
}
[NOIP2002 普及组] 过河卒
描述(中等,dp)
棋盘上 A点有一个过河卒,需要走到目标 B点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A 点 (0, 0)、B点(n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 A点能够到达 B点的路径的条数,假设马的位置(x,y)是固定不动的,并不是卒走一步马走一步。
注:马一次跳跃到达的点(x1,y1)和马原坐标(x,y)的关系是 ∣𝑥1−𝑥∣+∣𝑦1−𝑦∣=3,且𝑥1≠𝑥,𝑦1≠𝑦 ∣x1−x∣+∣y1−y∣=3,且x1=x,y1=y
数据范围: 1≤𝑛,𝑚≤20 1≤n,m≤20 ,马的坐标 0≤𝑥,𝑦≤20 0≤x,y≤20
1≤𝑎,𝑏,𝑐,𝑑≤1000 1≤a,b,c,d≤1000
输入描述:
仅一行,输入 n,m,x,y 四个正整数。分别表示B点坐标和马的坐标
输出描述:
输出路径总数
示例1
输入:
6 6 3 3
复制
输出:
6
复制
示例2
输入:
5 4 2 3
复制
输出:
3
复制
示例3
输入:
2 5 3 5
复制
输出:
1
#include <iostream>
#include<vector>
using namespace std;
int dx[8]={-1,-2,-2,-1,1,2,2,1};
int dy[8]={-2,-1,1,2,2,1,-1,-2};
int main() {
int n,m,x,y;
cin>>n>>m>>x>>y;
n++;
m++;
vector<pair<int,int>> point;
point.push_back({x,y});
for(int i=0;i<8;i++)
{
int tx=dx[i]+x;
int ty=dy[i]+y;
if(tx>=0&&tx<n&&ty>=0&&ty<m)
{
point.push_back({tx,ty});
}
}
vector<vector<long long>> dp(n+1,vector<long long>(m+1));
dp[0][1]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
bool flag=false;
for(auto e:point)
{
if(i-1==e.first&&j-1==e.second)
{
dp[i][j]=0;
flag=true;
}
}
if(!flag)
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
cout<<dp[n][m];
}
// 64 位输出请用 printf("%lld")