1.替换空格
public String replaceSpace(StringBuffer str) {
int count=0;
for(int i=0;i<str.length();i++){
char c=str.charAt(i);
if(c==' '){
count++;
}
}
int oldindex=str.length()-1;
int newstrlen=count*2+str.length();
str.setLength(newstrlen);
int newindex=str.length()-1;
for(;oldindex>=0&&newindex>=oldindex;oldindex--){
char c1=str.charAt(oldindex);
if(c1==' '){
str.setCharAt(newindex--,'0');
str.setCharAt(newindex--,'2');
str.setCharAt(newindex--,'%');
}else{
str.setCharAt(newindex--,c1);
}
}
return str.toString();
}
}
2.字符串的排列
class Solution {
LinkedList<String> res=new LinkedList();
char[] track;
public String[] permutation(String s) {
track=s.toCharArray();
backyard(0);
return res.toArray(new String[res.size()]);
}
void backyard(int depth){
if(depth==track.length){
res.add(String.valueOf(track));
return ;
}
Set set=new HashSet();
for(int i=depth;i<track.length;i++){
if(set.contains(track[i])){
continue;
}
set.add(track[i]);
swap(i,depth);
backyard(depth+1);
swap(depth,i);
}
}
void swap(int a,int b){
char tmp=track[a];
track[a]=track[b];
track[b]=tmp;
}
}
3.左旋字符串
public class Solution {
public String LeftRotateString(String str,int n) {
//字符串重新拼接 主要是要懂得java的常用方法
if(str==null||n>str.length()){
return str;
}
return str.substring(n)+str.substring(0,n);
}
}
4.翻转单词顺序列
public class Solution {
public String ReverseSentence(String str) {
//1.java StringBuffer的reverse方法
//2.栈先进后出 感觉不好用还是1好用
//3.滑动窗口 和1差不多
//先全部反转
StringBuffer str1=new StringBuffer(str);
str1.reverse();
StringBuffer result=new StringBuffer();
int j=0,Blanknum=0;
for(int i=0;i<str1.length();i++){
if(str1.charAt(i)==' '&&i!=str1.length()-1){
//局部反转回来
StringBuffer str2= new StringBuffer(str1.substring(j,i));
result.append(str2.reverse().toString()).append(" ");
j=i+1;
Blanknum++;
}
if(Blanknum!=0&&i==str1.length()-1){
StringBuffer str3= new StringBuffer(str1.substring(j,i+1));
result.append(str3.reverse().toString());
}
}
if(Blanknum==0){
return str;
}
return result.toString();
}
}
5.正则表达式匹配
6.表示数值的字符串
sollution1:java
import java.util.regex.Pattern;
public class Solution {
public boolean isNumeric(char[] str) {
//要学会正则表达式的写法
String pattern = "^[-+]?\\d*(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?$";
String s = new String(str);
return Pattern.matches(pattern,s);
}
}
sollution2:C++
#include<bits/stdc++.h>
class Solution {
public:
int StrToInt(string str) {
if(str.size()==0)return 0;
long long ans;
stringstream ss;
for(int i=0;i<str.size();i++){
if(i==0){
if((str[i]!='+'&&str[i]!='-')&&(str[i]-'0'>=9||str[i]-'0'<=0))
return 0;
}
if(i>0&&(str[i]-'0'>=9||str[i]-'0'<=0))return 0;
}
ss<<str;
ss>>ans;
if(ans>INT_MAX)return 0;
return ans;
}
};
7.字符流中第一个不重复的字符
import java.util.Queue;
import java.util.LinkedList;
import java.lang.Character;
public class Solution {
//可以用hashmap或者数组在插入的时候判断有无重复
//但因为这题不是一段字符串给完才判断,而是读一个返回一个值,所以每次用遍历的话,每次都是O(n)
//所以这里应该用队列
int[] charCnt = new int[128];
Queue<Character> queue = new LinkedList<Character>();
//Insert one char from stringstream
public void Insert(char ch)
{
if (charCnt[ch]++ == 0) //新来的单身字符,入队
queue.add(ch);
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
Character CHAR = null;
char c = 0;
while ((CHAR = queue.peek()) != null) {
c = CHAR.charValue();
if (charCnt[c] == 1) //判断是否脱单了,没脱单则输出
return c;
else queue.remove(); //脱单了就移出队列,它不会再回来了
}
return '#'; //队空,返回#
}
}
8.无重复字符的最长子串
用滑动窗口
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.length()==0)return 0;
unordered_set<char> lookup;
int left=0;
int maxstr=0;
for(int i=0;i<s.length();i++){
while(lookup.find(s[i])!=lookup.end()){
lookup.erase(s[left]);
left++;
}
maxstr=max(maxstr,i-left+1);
lookup.insert(s[i]);
}
return maxstr;
}
};
9.长度最小的子数组
思路:滑动窗口
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int left=0;
int minl=INT_MAX;//很大的值
int tmpsum=0;
for(int i=0;i<nums.size();i++){
tmpsum+=nums[i];
while(tmpsum>=s){
minl=min(minl,i-left+1);
tmpsum-=nums[left];
left++;
}
}
return (minl!=INT_MAX)?minl:0;
}
};
10.Z字形变换
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1) return s;
vector<string>stmp(min(int( s.size()),numRows));
int curRow=0;
bool flag=false;
for(char c:s){
stmp[curRow]+=c;
if(curRow==0||curRow==numRows-1){
flag=!flag;
}
curRow+=flag?1:-1;
}
string res;
for(string row:stmp){
res+=row;
}
return res;
}
};
思路:按列来存,存完一列到一列,控制行号curRow。当遇到转折,也就是行号是0或者是最后一行时,用一个标记flag来转换 最后用一个string来存。
11.最长回文子串
思路:用动态规划
class Solution {
public:
string longestPalindrome(string s) {
int len=s.size();
if(len==0||len==1)return s;
int maxl=1;
int start=0;
vector<vector<int> >dp(len,vector<int>(len));
for(int i=0;i<len;i++){
dp[i][i]=1;
if(s[i]==s[i+1]&&i<len-1){
start=i;
maxl=2;
dp[i][i+1]=1;
}
}
for(int l=3;l<=len;l++){
for(int i=0;i+l-1<len;i++){
int j=i+l-1;
if(s[i]==s[j]&&dp[i+1][j-1]==1){
start=i;
maxl=l;
dp[i][j]=1;
}
}
}
return s.substr(start,maxl);
}
};
class Solution {
public String longestPalindrome(String s) {
int len=s.length();
int maxl=1;
int st=0;
if(len==0||s==null)return "";
int[][] dp=new int[len][len];
for(int i=0;i<len;i++){
dp[i][i]=1;
if(i<len-1){
if(s.charAt(i)==s.charAt(i+1)){
dp[i][i+1]=1;
maxl=2;
st=i;
}else{
dp[i][i+1]=0;
}
}
}
for(int i=len-1;i>=0;i--){
for(int j=i+1;j<len;j++){
if(j-i==1)continue;
if(s.charAt(i)==s.charAt(j)){
dp[i][j]=dp[i+1][j-1];
if(dp[i][j]==1&&maxl<(j-i+1)){
maxl=j-i+1;
st=i;
}
}else{
dp[i][j]=0;
}
}
}
return s.substring(st,maxl+st);
}
}
12.检查替换后的词是否有效
法1:
class Solution {
public:
bool isValid(string S) {
if(S.size()<=2)return false;
if(S.size()%3!=0)return false;
stack<char>st;
for(char c:S){
if(c!='c')
st.push(c);
else{
if(st.empty())return false;
char t1=st.top();
st.pop();
if(st.empty())return false;
char t2=st.top();
st.pop();
if(t1!='b')return false;
if(t2!='a')return false;
}
}
if(!st.empty())
return false;
return true;
}
};
根据题意,不难发现合法的字符串都是在abc的空隙中再插入abc,得出的新字符串中再插入abc。。。 所以用一个栈来存字符a和b,如果碰到c,就pop掉栈顶的两个字符看看c前面的第一个字符是不是b,第二的字符是不是a即可。
法二:
class Solution {
public boolean isValid(String S) {
while(S.contains("abc")){
S=S.replaceAll("abc","");
}
return S.equals("");
}
}
13.最长公共前缀
class Solution {
public String longestCommonPrefix(String[] strs) {
String prefix="";
if(strs.length==0)return prefix;
prefix=strs[0];
for(int i=1;i<strs.length;i++){
while(strs[i].indexOf(prefix)!=0){
prefix=prefix.substring(0,prefix.length()-1);
if(prefix.isEmpty())return "";
}
}
return prefix;
}
}
14.外观数列
先读懂题
找规律
发现每一个新状态都是从前一个状态得来 则用递归
class Solution {
public String countAndSay(int n) {
StringBuilder res=new StringBuilder();
if(n==1)return "1";
int cur=1;
int pre=0;
//递归
String s=countAndSay(n-1);
for(cur=1;cur<s.length();cur++){
if(s.charAt(pre)!=s.charAt(cur)){
int count=cur-pre;
res.append(count).append(s.charAt(pre));
pre=cur;
}
}
if(pre!=cur){
int count=cur-pre;
res.append(count).append(s.charAt(pre));
}
return res.toString();
}
}
14.实现strStr()
模式匹配:KMP算法
15.回文子串
class Solution {
public int countSubstrings(String s) {
int length=s.length();
if(s.equals("")||length==0)return 0;
int[][]dp=new int[length][length];
int sum=length;
for(int i=0;i<length;i++)dp[i][i]=1;
for(int i=length-1;i>=0;i--){
for(int j=i+1;j<length;j++){
if(s.charAt(i)==s.charAt(j)){
if(j-i==1){
dp[i][j]=1;
}else{
dp[i][j]=dp[i+1][j-1];
}
}else{
dp[i][j]=0;
}
if(dp[i][j]==1)sum++;
}
}
return sum;
}
}
16.括号生成
class Solution {
public List<String> generateParenthesis(int n) {
List<String>res=new ArrayList();
if(n==0)return res;
dfs("",n,n,res);
return res;
}
void dfs(String cur,int left,int right,List<String>res){
if(left==0&&right==0){
res.add(cur);
return ;
}
if(left>right){
return;
}
if(left>0){
dfs(cur+"(",left-1,right,res);
}
if(right>0){
dfs(cur+")",left,right-1,res);
}
}
}
思路:深度优先搜索
17.回文数
class Solution {
public boolean isPalindrome(int x) {
if(x<0)return false;
int help=1;
int tmp=x;
while(tmp>=10){
help*=10;
tmp/=10;
}
//help/=10;
// System.out.println(help)
while(x!=0){
if(x/help!=x%10){
return false;
}
x=x%help/10;
help/=100;
}
return true;
}
}
18.反转字符串里的单词)(同4)
class Solution {
public String reverseWords(String s) {
String[] tmp=s.trim().split("\\s+");
String res="";
for(int i=tmp.length-1;i>0;i--){
res+=tmp[i]+" ";
}
return res+tmp[0];
}
}
知识点:
-
\s表示 空格,回车,换行等空白符,+号表示一个或多个的意思
-
split("\s+") 按空格,制表符等进行拆分
-
split(" +") 按空格进行拆分(也就是说只有按空格键流出来的空白才会是拆分的一句),这里用这个也可以