字符串类型面试题目总结

字符串系列题目一览:

1.t1是否有与t2树拓扑结构相同的子树
2.判断两个字符串是否互为变形词?
3.判断两个字符串是否为旋转词?
4.字符串str,请在单词间做逆序调整。
5.给字符串str和一个整数i,i代表str中的位置,将str[0...i]移到右侧,str[i+1...N-1]移到左侧
6.将字符串数组strs拼接一个字符串,字典顺序最小
7.将str中空格字符替换成"%20",假设有足够空间
8.判断字符串是不是有效的括号字符串 str="(()" 返回false
9.判断字符串最长无重复子串的长度 str="abcd" 返回3

1.t1是否有与t2树拓扑结构相同的子树

2.判断两个字符串是否互为变形词?

两个字符串出现的字符种类和每个字符种类出现的次数一样,成为互为变形词。
可以声明256的数组,但是在Java中一个char字符类型占用两个字节,16位65535,所以可以声明65536大小的数组。
也可以使用哈希表解决这个问题。key为字符,value存储出现的次数。str1增加,str2减少。遍历结束正确的结果刚好为0,说明字符种类与出现次数相同。

    public static boolean distortion_test(String s1,String s2){
         if(s1==null||s2==null||s1.length()!=s2.length()){  
                return false;  
            }
        char[] c1=s1.toCharArray();
        char[] c2=s2.toCharArray();
        int[] k=new int[256];
        for(int i=0;i<c1.length;i++){
            k[c1[i]]++;
        }
        for(int i=0;i<c2.length;i++){
            if(k[c2[i]]==0)
                return false;
            k[c2[i]]--;
        }
        return true;
    }
    
    public static boolean distortion_test2(String s1,String s2){
         if(s1==null||s2==null||s1.length()!=s2.length()){  
                return false;  
            }  
        char[] c1=s1.toCharArray();
        char[] c2=s2.toCharArray();
        Map<Character, Integer> map=new HashMap<Character,Integer>();
        for(int i=0;i<c1.length;i++){
            if(map.get(c1[i])==null)
                map.put(c1[i], 1);
            else        
                map.put(c1[i],map.get(c1[i])+1);
        }
        for(int i=0;i<c2.length;i++){
            if(map.get(c2[i])==null||map.get(c2[i])==0)
                return false;
            else
                map.put(c2[i], map.get(c2[i])-1);
        }
        return true;
    }

3.判断两个字符串是否为旋转词?

把str前面任意部分挪到后面形成的字符串叫做str旋转词
a="abcd" b="cdab" 返回true

4.字符串str,请在单词间做逆序调整。

"pig loves dog"逆序成"dog loves pig"
构造一个字符串全体逆序方法。
先对将整体逆序 --->"god sevol gip",再循环到空格处,对单词进行逆序--->"dog loves pig",得到结果。

public static void inverse(char[] ch,int begin,int end){
        while(begin<end){
            char temp=ch[begin];
            ch[begin]=ch[end];
            ch[end]=temp;
            begin++;
            end--;
        }
    }
    
    public static String swapWord(String s){
        char[] a=s.toCharArray();
        inverse(a,0,a.length-1);
        int blank=-1;
        for(int i=0;i<a.length;i++){
            if(a[i]==' '){
                int nextBlank=i;
                inverse(a,blank+1,nextBlank-1);
                blank=nextBlank;
            }
        }
        inverse(a,blank+1,a.length-1);
        return (new String(a));
    }

5.给字符串str和一个整数i,i代表str中的位置,将str[0...i]移到右侧,str[i+1...N-1]移到左侧

str="abcde",i=2 调整后 str="deabc"
同上题,先构造逆序方法。对str逆序--->"edcba",然后再根据i的位置对两侧分别逆序,--->"deabc"

public static void inverse(char[] ch,int begin,int end){
        while(begin<end){
            char temp=ch[begin];
            ch[begin]=ch[end];
            ch[end]=temp;
            begin++;
            end--;
        }
    }
    
    public static String shift(String s,int i){
        char[] ch=s.toCharArray();
        inverse(ch,0,ch.length-1);
        inverse(ch,0,ch.length-i-2);
        inverse(ch,ch.length-i-1,ch.length-1);
        return new String(ch);
    }
    
    public static void main(String args[]){
        String s="abcde";
        System.out.println(shift(s,3));
    }

6.将字符串数组strs拼接一个字符串,字典顺序最小

strs=["abc","de"] 拼成"abcde"
strs=["b","ba"]拼成"bab"
比较的内容为o1+o2>o2+o1,是两个字符串连接后的大小,而不是单独字符串的比较。

  public static String findSmallest(String[] strs, int n) {
            // write code here
            Arrays.sort(strs, new Comparator<String>() {
     
                @Override
                public int compare(String o1, String o2) {
                    //此方法如果这个字符串是等参数字符串那么返回值0,==  
                    //如果这个字符串是按字典顺序小于字符串参数那么返回小于0的值,<  
                    //如果此字符串是按字典顺序大于字符串参数那么一个大于0的值 >  
                    String s1=o1+o2;
                    String s2=o2+o1;
                    return s1.compareTo(s2);
                }
            });
             
            StringBuilder sb=new StringBuilder();
            for(int i=0;i<n;i++){
                sb.append(strs[i]);              
            }
            return sb.toString();     
      }
    
      public static void main(String args[]){
          String s[]=new String[]{"ba","b"};
          System.out.println(findSmallest(s, s.length));
      }

7.将str中空格字符替换成"%20",假设有足够空间

s=s.replace(" ", "%20");

8.判断字符串是不是有效的括号字符串 str="(()" 返回false

    设置num,代表‘(’与‘)’出现此时差值,(就++,)就--,最后应该=0

9.判断字符串最长无重复子串的长度 str="abcd" 返回3

求出每个字符结尾的情况下,最长无重复字符子串的长度,并找出最大值返回
哈希表map --> 统计了每种字符之前出现的位置
整型数组preArr-->代表以s[i]结尾的情况下,最长无重复子串的长度


当循环中,遇见字符重复出现,求该字符的最大不重复子串时。需要比较:上一次该字符出现位置+1与 该字符左边字符的最长无重复子串。如上图位置A与位置B。选择A与B中靠右的点,该点到c的距离便是c的最长无重复子串。(A与B之间必然会重复,所以选择靠右的点)

public static int longestSubstring(String A, int n) {
        //charPosition统计A中每种字符之前出现的位置
        Map<Character, Integer> charPosition = new HashMap<Character, Integer>();
        //preArr代表以s[i-1]结尾的情况下,最长无重复子串的长度
        int[] preArr = new int[A.length()];
        char[] str2charArr = A.toCharArray();
        //从头到尾遍历str2charArr,统计出以每个字符为当前位置的向前最长无重复子串的长度
        for(int i=0; i<A.length(); i++){
            Integer lastPosOfChar = charPosition.get(str2charArr[i]);
            if(lastPosOfChar == null){//说明当前字符第一次出现
                //更新最长无重复子串的长度
                preArr[i] = i == 0 ? 1 : preArr[i-1] + 1;
                //记录当前字符出现的位置
                charPosition.put(str2charArr[i], i);
            }
            else{//当前字符不是第一次出现(既然不是第一次出现,那也不是在第一个位置),也就是之前出现过该字符
                //获取前一个字符最长无重复子串的长度
                int aPos = lastPosOfChar + 1; //上一次出现该字符的位置+1
                int unRepeatLen = preArr[i-1];//以该字符左侧一位字符为标准的最长无重复子串的长度
                int bPos = i - unRepeatLen;
                if(aPos >= bPos){
                    //当前位置的最长无重复子串长度
                    preArr[i] = i - aPos + 1;
                }
                else{
                    //当前位置的最长无重复子串长度
                    preArr[i] = unRepeatLen + 1;
                }
                //更新当前字符出现的位置
                charPosition.put(str2charArr[i], i);
            }
        }
        //遍历preArr,最大值即为所求
        int max = preArr[0];
        for(int i: preArr) if(i > max) max = i;
        return max;
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容