资讯专栏INFORMATION COLUMN

我的面试准备过程---字符串相关(更新中)

周国辉 / 2157人阅读

摘要:字符串简介内置类型,不可理性,要更改的话考虑转,之类对来说,一个的范围,位面试题总体分析和数组相关,内容广泛概念理解字典序,哪个排在字典前面,哪个字典序就小简单操作插入删除字符,旋转规则判断罗马数字转换,是否是合法的整数浮点数数字运算套数加

字符串简介

String 内置类型,不可理性,要更改的话考虑转StringBuffer,StringBuilder,char[]之类

对java来说,一个char的范围 [0,65535],16位

面试题总体分析

和数组相关,内容广泛

概念理解:字典序,哪个排在字典前面,哪个字典序就小

简单操作: 插入、删除字符,旋转

规则判断 罗马数字转换,是否是合法的整数、浮点数

数字运算(套数加法、二进制加法)

排序、交换(partition过程)

字符计数(hash): 变位词

匹配(正则表达式、全串匹配、KMP、周期判断)

动态规划(LCS、编辑距离、最长回文子串)

搜索(单词变换、排列组合)

例1 把一个0-1串进行排序,可以交换任意两个位置,问最少交换的次数

思路:快排partition 最左边0和最右边的1都可以不管

    public int exchangeTimes(String s){
        int answer = 0;
        for(int i = 0, j = s.length() - 1; i < j; i++, j--){
            for(; i < j && s.charAt(i) == "0"; i++);
            for(; i < j && s.charAt(j) == "1"; j--);
            if(i < j) answer++;
        }
        return answer;
    }
例2 删除一个字符串所有的a,并且复制所有的b.注:字符数组足够大
    public void solve(char[] chars){
        //先删除a,可以利用原来字符串的空间,过程类似插入排序
        int n = 0;//删除a后的字符数组长度
        int bCount = 0;
        for(int i = 0; s[i] != ""; i++){
            if(chars[i] == "a"){
                chars[n++] = chars[i];
            }
            if(chars[i] == "b"){
                bCount++;
            }
        }
        //从后往前复制
        //步骤1. 遍历计算新串长度,b出现的次数2. 从后往前遍历 3.旧串复制,如果遇到b,复制两遍
        int newLength = n + bCount;
        chars[newLength] = "";
      for(int i = n, j = newLength - 1; i >= 0; i--){
            chars[j--] = chars[i];
            if(chars[i] == "b"){
                chars[j--] = "b"; 
        }
    }
思考题:如何把字符串的空格变成"%20"
    public void replaceSpace(char[] chars){
        int length = 0;
        int spaceCount = 0;
        for(int i = 0; chars[i] != ""; i++){
            length++;
            if(chars[i] == " "){
                spaceCount++;
            }
        }

        int newLength = length + 2 * spaceCount;
        chars[newLength] = "";
        for(int i = newLength - 1, j = length; j >= 0; j--){
            if(chars[j] == " "){
                char[i] = "0";
                char[--i] = "2";
                char[--i] = "%"; 
            }else{
                char[i--] = char[j];
            }
        }
    }
例3 一个字符串只包含*和数字,请把它的*号都放开头。

方法1 快排partition,因为过程不稳定,所以数字相对顺序会变化

    public void sortStar(char[] chars){
        for(int i = 0 , j = 0; j < a.length; j++){
            if(chars[i] == "*"){
                swap(a[i++], a[j])
            }
        }
    }

    private void swap(char[] chars, int i, int j){
        char temp = chars[i];
        chars[i] = chars[j];
        chars[j] = temp;
    }

方法2 倒着处理

     public void sortStar(char[] chars){
        int length = chars.length;
        int i = length - 1;
        for(int j = length - 1; j >= 0; j--){
            if(chars[j] != "*"){
                chars[i--] = chars[j];
            }
        }
        while(i >= 0){
            chars[i--] = "*";
        }
    }

注意:以上两种解法的异同,方法1,用到交换和快排partition思想,但是无法保证数字的顺序;方法2,使用倒着向前处理的思想,如果必须用交换,只能采用方法1

例4 单词翻转
翻转句子中全部的单词,单词内容不变,例如I"m a student. 变为student. a I"m
思路:in-place翻转 字符串第i位到第j位
    while(i < j) swap(s[i++], s[j--]);
1. 翻转整个句子:.tneduts a m"I
2. 每个单词多带带翻转: students. a I"m

这段代码写得非常丑陋
    public void revertStr(char[] chars){
    int length = chars.length;
    //翻转整个句子
    revertInPlace(chars, 0, length - 1);
    //翻转每个单词
    String str = new String(chars);
    String[] strs = str.split(" ");
    int wordCounts = strs.length;
    int[] eachLength = new int[wordCounts];
    int i = 0;
    for(String s : strs){
        eachLength[i++] = s.length();
    }
    int start = 0;
    for(int j = 0; j < wordCounts; j++){
        revertInPlace(chars, start, start + eachLength[j] - 1);
        start += eachLength[j] + 1;
    }
}
private void revertInPlace(char[] chars, int i, int j){
    while(i < j){
        swap(chars, i++, j--);
    }
}
private void swap(char[] chars, int i, int j){
    char temp = chars[i];
    chars[i] = chars[j];
    chars[j] = temp;
}
思考题:字符串循环移位
abcd 移动1次为bcda,移动两次为cdab,移动三次为dabc
结论:长度为n,移动m次,相当于移动m%n次
    - 前m%n位翻转,后n-m%n位翻转
    - 总体再翻转一次
public void circularMove(char[] chars, int m){
    int n = chars.length;
    revertInPlace(chars, 0, m % n - 1);
    revertInPlace(chars, m % n, n - 1);
    revertInPlace(chars, 0, n - 1);
}
private void revertInPlace(char[] chars, int i, int j){
    while(i < j){
        swap(chars, i++, j--);
    }
}
private void swap(char[] chars, int i, int j){
    char temp = chars[i];
    chars[i] = chars[j];
    chars[j] = temp;
}
总结:

in-place(原地)理解

本身为O(1)空间

递归,堆栈空间可以不考虑

原地相关的问题

字符串循环左移、右移

快排partition相关

滑动窗口

能达到O(n)的时间复杂度

O(1)的空间复杂度

规则相关---细致

匹配(暴力):KMP比较少见

Manacher----要求比较高的笔试

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70171.html

相关文章

  • 一位大佬的亲身经历总结:简历和面试的技巧

    摘要:我觉得了解简历和面试的技巧可以帮助你更好的去学习重要的知识点以及更好地去准备面试以及面试,说实话,我个人觉得这些东西还挺重要的。在本文里,我将介绍我这段时间里更新简历和面试的相关经历。 分享一篇很不错的文章!本文作者曾经写过《Java Web轻量级开发面试教程》和 《Java核心技术及面试指南》这两本书。我觉得了解简历和面试的技巧可以帮助你更好的去学习重要的知识点以及更好地去准备面试以...

    pingan8787 评论0 收藏0
  • 2018年, 我的前端面试复盘

    摘要:技术一面一面主要考察基础,有些会有技术笔试,比如腾讯,。腾讯的面试官就很喜欢问,安全,浏览器缓存方面的问题,计算机基础,但是要懂为什么。 这篇文章简单总结下2018年内我的一些前端面试经历, 在这简单分享一下,希望对大家有所启发。 楼主在深圳,毕业两年。面的主要是深圳的几家公司。 包括: 腾讯, 蚂蚁金服, Lazada, Shopee, 有赞 等 。 楼主在准备面试前, 想着复习一...

    Yujiaao 评论0 收藏0
  • 求职准备 - 收藏集 - 掘金

    摘要:一基础接口的意义百度规范扩展回调抽象类的意义想不想通过一线互联网公司面试文档整理为电子书掘金简介谷歌求职记我花了八个月准备谷歌面试掘金原文链接翻译者 【面试宝典】从对象深入分析 Java 中实例变量和类变量的区别 - 掘金原创文章,转载请务必保留原出处为:http://www.54tianzhisheng.cn/... , 欢迎访问我的站点,阅读更多有深度的文章。 实例变量 和 类变量...

    cuieney 评论0 收藏0
  • 我的前端面试

    摘要:前言这次找工作也面了好几家公司,也通过了好几家公司的面试,毕竟之前也准备了一段时间,所以面试的时候心里也不是很虚。的代码分割怎么实现的说说刚才提到的和的区别前端缓存怎么实现扯扯强缓存和协商缓存,重点问了如何实现缓存二面就聊了项目。。。 前言 这次找工作也面了好几家公司,也通过了好几家公司的面试,毕竟之前也准备了一段时间,所以面试的时候心里也不是很虚。 这里记录一下面试过程中被问到的问题...

    meteor199 评论0 收藏0
  • 一个 16年毕业生所经历的 PHP 面试

    摘要:正确做法是给加索引,还有联合索引,并不能避免全表扫描。 前言:有收获的话请加颗小星星,没有收获的话可以 反对 没有帮助 举报三连 有心的同学应该会看到我这个noteBook下面的其它知识,希望对你们有些许帮助。 本文地址 时间点:2017-11 一个16年毕业生所经历的php面试 一、什么是面试 二、面试准备 1. 问:什么时候开始准备? 2. 问:怎么准备? 三、面试...

    dabai 评论0 收藏0

发表评论

0条评论

周国辉

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<