1.给你一个字符串 s,找到 s 中最长的回文子串。
https://leetcode-cn.com/problems/longest-palindromic-substring/
思路:1.动态规划,注意应该“斜着”构造表2.更高效的算法,基于中心扩展,思路如下图
动态规划代码:
#include<vector>
class Solution {
public:
string longestPalindrome(string s) {
//动态规划
//s[i,j]=s[i+1,j-1]&&(s[i]==s[j])
//s[i,i]=true
//s[i,i+1]=(s[i]==s[i+1])
int size=s.length();
vector<vector<bool>> dp(size,vector<bool>(size));
for(int l=0;l<size;l++){
for(int i=0;i+l<size;i++){
int j=i+l;//注意动态规划的求表顺序,斜着来!
if(i==j){
dp[i][j]=true;
}else if((i+1)==j){
if(s[i]==s[j]){
dp[i][j]=true;
}else{
dp[i][j]=false;
}
}else{
if((s[i]==s[j])&&dp[i+1][j-1]){
dp[i][j]=true;
}else{
dp[i][j]=false;
}
}
}
}
//找出最长的子串
int max=0,begin=0;
for(int i=0;i<size;i++){
for(int j=i;j<size;j++){
if(dp[i][j]&&((j-i+1)>max)){
max=j-i+1;
begin=i;
}
}
}
return s.substr(begin,max);
}
};
2.将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
请你实现这个将字符串进行指定行数变换的函数
string convert(string s, int numRows);
https://leetcode-cn.com/problems/zigzag-conversion/
思路:1.找规律(和方法二比起来简直就是小学生!)
2.用numrows个列表和一个表示方向的标志,模拟z字型存放的顺序(到头换方向),最后将列表相接即可 特别的,当numrows为1时,需要特殊判断,因为此时本身就在边界了,加减后超出范围容易下标越界!!
代码:
class Solution {
public:
string convert(string s, int numRows) {
if(numRows!=1){
int flag=1,k=0;
string result[numRows];
for(int i=0;i<s.length();i++){
result[k]=result[k]+s[i];
k+=flag;
if(k==0||(k==(numRows-1))){//到头换方向
flag*=-1;
}
}
string r;
for(int i=0;i<numRows;i++){
r=r+result[i];
}
return r;
}else{
return s;
}
}
};
3.编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
https://leetcode-cn.com/problems/number-of-1-bits/
思路:可以挨个遍历,但是这样会检查到很多没必要的0,我们可以直接从最后一位1开始数,也就是将该数减一,这样相当于 x1000 & x0111 (此处是一个例子,仅用于解释该方法可以每次将最后一位1置0),这样当该数为0时即可得到1的个数。
class Solution {
public:
int hammingWeight(uint32_t n) {
int num=0;
while(n!=0){
n=n&(n-1);
num++;
}
return num;
}
};