剑指offer 字符串

字符串

常量池(intern())

字符串转成double

字符串与StringBuilder(非线程安全),StringBuffer(线程安全)区别

遍历

ASCII码

正则表达式

final类型(理解concurrentHashMap和hashMap区别)

java中默认分配16的字符大小的空间

1.大小

StringBuffer sb = new StringBuffer("hello");  
        System.out.println(sb.length());;  
        System.out.println(sb.capacity()); 

输出:

5

21=5+16

2.类型转换:

题目(面试题49):把字符串转换成整数

解法一:逐个字符判断然后转换,大问题分解成小问题,各种边界情况的考虑以及处理;

解法二:java中的实现,Integer.parseInteger(String);

public class Solution {  
    public int StrToInt(String str) {  
        int len=str.length();  
        if((str==null)||(len==0))  
            return 0;  
        double result=0;  
        for(int i=0;i<len;i++){  
            double temp=(str.charAt(i)-'0');  
            if((temp>=0)&&(temp<=9)){  
                temp=temp*Math.pow(10,len-1-i);  
                result=result+temp;  
            }  
            else if(((str.charAt(i)-'+')!=0)&&((str.charAt(i)-'-')!=0))  
                return 0;  
        }  
        if((str.charAt(0)-'-')==0)  
            result=-result;  
        return (int)result;  
    }  
}  

3. 遍历

题目(面试题4)替换空格:

解法一:c或者c++里面用字符数组表示字符串,遍历搜索,然后替换,双指针(新开数组);

解法二:Java里直接操作StringBuilder对象;

public class Solution {
    public String replaceSpace(StringBuilder str) {
            int i;
            for(i=0;i<str.length();i++){
                if(str.charAt(i)==' '){
                    str.replace(i, i+1, "%20");
                }
            }
            return str.toString();
    }
}
相关题目:

a. 有两个排序的数组A1和A2,内存在A1的末尾有足够的空余空间容纳A2,请实现一个函数,把A2中的所有数字插入到A1中并且所有的数字是排序的。

解法:因为从前往后复制很多数字都重复复制多次,所以考虑从后往前复制,减少复制移动次数。
4.统计

题目(面试题35):第一个只出现一次的字符

解法一:直接插入排序的思想,O(n2);

解法二:借助哈希表统计次数,其实数组也是一种哈希表,ASCII码相当于hash函数;

题目(面试题55):字符流中第一个不重复的字符

import java.util.HashMap;
import java.util.Map;
public class Solution {
        private StringBuffer str=new StringBuffer();
        private StringBuffer result=new StringBuffer();
        //Insert one char from stringstream
        public void Insert(char ch)
        {
            str.append(ch);
             
            result.append(FirstAppearingOnce());
        }
      //return the first appearence once char in current stringstream
        public char FirstAppearingOnce()
        {
            Map<Character,Integer> map=new HashMap<Character,Integer>();
            for(int i=0;i<str.length();i++){
                if(!map.containsKey(str.charAt(i))){
                    map.put(str.charAt(i), 1);
                }
                else{
                    int temp=map.get(str.charAt(i))+1;
                    map.put(str.charAt(i),temp);
                }
            }
             
            for(int i=0;i<str.length();i++){
                if(map.get(str.charAt(i))==1)
                    return str.charAt(i);
            }
            return '#';
        }
}


相关题目:

a. 定义一个函数,输入两个字符串,从第一个字符串中删除在第二个字符串中出现过的所有字符

解法:第一个字符串遍历,charAt(),第二个字符串存到哈希表里,查找O(1)。

b. 定义一个函数,删除字符串中所有重复出现的字符

c. 定义一个函数,判断是否是变位词:即如果两个单词出现的字母相同,并且每个字符出现的次数也相同,那就称为变位词

5.排列与组合

题目(面试题28)字符串的排列

解法一:先大问题分解成小问题,去重,构造新字符串,递归

import java.util.ArrayList;  
public class Solution {  
    public ArrayList<String> Permutation(String str) {  
       ArrayList<String> result=new ArrayList<String>();  
        if(str==null || str.length()==0)  
            return result;  
        if(str.length()<=1){  
            result.add(str);  
            return result;  
        }  
        int len=str.length();  
        for(int i=0;i<len;i++){  
            char ch=str.charAt(i);  
            if(i>0&&ch==str.charAt(i-1))  
                continue;  
            String nstr=remove(str,i);  
            ArrayList<String> temp=Permutation(nstr);  
            for(int j=0;j<temp.size();j++){  
                result.add(ch+temp.get(j));  
            }  
        }  
        return result;  
    }  
    private String remove(String str,int i){  
        if(i==0) return str.substring(1,str.length());  
        if(i==str.length()-1) return str.substring(0, i);  
        return str.substring(0, i)+str.substring(i+1, str.length());  
    }  
}  
相关题目:
a. 字符串的组合

public static void combiantion(char chs[]){    
    if(chs.length == 0) return ;    
        
    Stack<Character> stack = new Stack<Character>();    
    for(int i = 1; i <= chs.length; i++){    
        combine(chs, 0, i, stack);    
    }    
}    
//从字符数组中第begin个字符开始挑选number个字符加入list中    
public static void combine(char []chs, int begin, int number, Stack<Character> stack){    
       if(number == 0){    
        System.out.println(stack.toString());    
        return ;    
       }    
       if(begin == chs.length){    
        return;    
       }    
       stack.push(chs[begin]);    
       combine(chs, begin + 1, number - 1, stack);    
       stack.pop();    
       combine(chs, begin + 1, number, stack);    
}    
b. 国际象棋的八皇后问题,即是先求全排列
6. 翻转

题目(面试题42):翻转单词顺序

解法一:

public class Solution {
    public String ReverseSentence(String str) {
            if(str==null)
                return null;
            if(str.trim().equals(""))
                return str;
            String[] strs=str.split(" ");
            StringBuilder result=new StringBuilder();
            for(int i=strs.length-1;i>=0;i--){
                result.append(strs[i]+" ");
            }
            return result.toString().trim();         
    }
}
解法二:双指针,理解java中双指针的思想

相关题目:

a. 左旋转字符串:如果左旋转的n比字符串的长度还大的时候取余操作

public class Solution {  
    public String LeftRotateString(String str,int n) {         
        int len=str.length();  
        if((str==null)||(len==0))  
            return str;    
        n=n%len;  
        StringBuffer result=new StringBuffer();  
        for(int i=n;i<str.length();i++){  
            result.append(str.charAt(i));  
        }  
        for(int i=0;i<n;i++){  
            result.append(str.charAt(i));  
        }  
        return result.toString();  
    }  
}  
7.匹配 KMP

题目(面试题53):正则表达式匹配

题目(面试题54):表示数值的字符串

精通KMP算法 July

前缀

后缀

最大前缀后缀公共元素长度

求next数组:相当于把最大长度表整体右移一位,然后初始值赋为-1;

对于给定的模式串:ABCDABD,它的最大长度表及next 数组分别如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值