1 替换空格-剑指offer
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
方法一
public class Solution {
public String replaceSpace(StringBuffer str) {
StringBuffer result = new StringBuffer();
for(int i = 0;i < str.length();i++){
if(String.valueOf(str.charAt(i)).equals(" ")){
result.append("%20");
}
else{
result.append(str.charAt(i));
}
}
return result.toString();
}
}
方法二 简单的
public class Solution {
public String replaceSpace(StringBuffer str) {
return str.toString().replaceAll(" ","%20");
}
}
2最长公共前缀-leetcode
Leetcode: 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。
输入: [“flower”,“flow”,“flight”]
输出: “fl”
以第一个字符串为标准,和剩下的字符串一个个进行比较,如不相同则返回之前对比完且相同的字符子串,注意此处对比第一个子串index不能越界大于剩下的子串
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs == null||strs.length == 0)
return "";
for(int i = 0;i < strs[0].length();i++){
char c = strs[0].charAt(i);
for(int j = 1;j < strs.length;j++){
if(i >= strs[j].length()||c != strs[j].charAt(i)){
return strs[0].substring(0,i);
}
}
}
return strs[0];
}
}
3最长回文串
LeetCode: 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串
class Solution {
public int longestPalindrome(String s) {
HashSet<Character> hashset = new HashSet<Character>();
int count = 0;
for(int i = 0;i < s.length();i++){
if(!hashset.contains(s.charAt(i))){
hashset.add(s.charAt(i));
}
else{
hashset.remove(s.charAt(i));
count++;
}
}
return hashset.isEmpty()?count * 2:count * 2 + 1;
}
}
4验证回文串
LeetCode: 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 说明:本题中,我们将空字符串定义为有效的回文串,即不考虑空格。
class Solution {
public boolean isPalindrome(String s) {
if(s.length() == 0)
return true;
int l = 0,r = s.length() -1;
while(l < r){
if(!Character.isLetterOrDigit(s.charAt(l))){
l++;
}else if(!Character.isLetterOrDigit(s.charAt(r))){
r--;
}else{
if(Character.toLowerCase(s.charAt(l)) == Character.toLowerCase(s.charAt(r))){
l++;
r--;
}else{
return false;
}
}
}
return true;
}
}
5寻找最长回文子串
LeetCode: 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
class Solution {
private int index = 0;
private int len = 0;
public String longestPalindrome(String s) {
if(s.length() <= 1)
return s;
for(int i = 0;i < s.length() - 1;i++){
funtion(s,i,i);
funtion(s,i,i + 1);
}
实际返回的是[index] - [index + len - 1]
return s.substring(index,index + len);
}
public void funtion(String s,int l,int r){
while(l >= 0&&r < s.length()&&s.charAt(l) == s.charAt(r)){
l--;
r++;
}
//注意此时的l r 位置处于不匹配的位置上
if(len < r - l + 1 - 2){
len = r - l + 1 - 2;
index = l + 1;
}
}
}
6最长回文子序列-动态规划 重要
最长回文子序列 给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000。最长回文子序列和上一题最长回文子串的区别是,子串是字符串中连续的一个序列,而子序列是字符串中保持相对位置的字符序列,例如,"bbbb"可以是字符串"bbbab"的子序列但不是子串。
解题思路:
状态 f[i][j] 表示 s 的第 i 个字符到第 j 个字符组成的子串中,最长的回文序列长度是多少。
转移方程 如果 s 的第 i 个字符和第 j 个字符相同的话
f[i][j] = f[i + 1][j - 1] + 2
如果 s 的第 i 个字符和第 j 个字符不同的话
f[i][j] = max(f[i + 1][j], f[i][j - 1])
然后注意遍历顺序,i 从最后一个字符开始往前遍历,j 从 i + 1 开始往后遍历,这样可以保证每个子问题都已经算好了。
初始化 f[i][i] = 1 单个字符的最长回文序列是 1
结果 f[0][n - 1]
class Solution {
public int longestPalindromeSubseq(String s) {
int n = s.length();
int[][] arr = new int[n][n];
//定义arr[i][j]为索引i到j子字符串中最大的回文子序列
//则初始化arr[i][i]为1
for(int i = n - 1;i >= 0;i--){
arr[i][i] = 1;
for(int j = i + 1;j < n;j++){
//转移方程
if(s.charAt(i) == s.charAt(j)){
arr[i][j] = arr[i + 1][j - 1] + 2;
}else{
arr[i][j] = Math.max(arr[i + 1][j],arr[i][j - 1]);
}
}
}
return arr[0][n -1];
}
}
7把字符串转换成整数
剑指offer: 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
public class Solution {
public int StrToInt(String str) {
if(str.length() == 0){
return 0;
}
char[] arr = str.toCharArray();
//默认为正
int flag = 1;
int start = 0;
//判断符号
if(arr[0] == '-'){
start = 1;
flag = -1;
}
else if(arr[0] =='+'){
start = 1;
}
int res = 0;
for(int i = start;i < arr.length;i++){
int temp;
if(Character.isDigit(arr[i])){
temp = arr[i] - '0';
}else{
return 0;
}
res = res * 10 + temp;
}
return flag == 1?res:-res;
}
}