【面试算法】——字符串(五)

一、空格替换

题型:

给定一个字符串str,将其中所有空格字符替换成“%20”,假设str后面有足够的空间。

思路:

面对这种题目,我们首先需要计算替换后的数组的长度,我们先遍历原数组,记录数组中的空格数,例如:“a b c”中有两个空格,那么替换后的数组数为5+2*2=9。然后我们从下标为8的位置开始,从后往前依次放入c,0,2,%,直到全部添加完毕。

代码举例:

import java.util.*;

public class Replacement {
    public String replaceSpace(String iniString, int length) {
        // write code here
        //首先遍历数组,找出空格的数量
        int spaceCount = 0;   //表示空格的数量
        for(int i=0;i<length;i++){
            if(iniString.charAt(i) == ' '){
                spaceCount++;
            }
        }
        //创建更改后的数组
        char[] chs = new char[length+spaceCount*2];
        //倒序遍历,遇到‘ ’则替换成%20
        int len = chs.length-1;
        for(int i=length-1;i>=0;i--){
            if(iniString.charAt(i) == ' '){
                chs[len--] = '0';
                chs[len--] = '2';
                chs[len--] = '%';
            }else{
                chs[len--] = iniString.charAt(i);
            }
        }
        return String.valueOf(chs);
    }
}

二、合法括号判断

题型:

给定一个字符串str,判断是不是整体有效的括号字符串。实质就是,一个字符串中只有左括号和右括号这两种符号,让我们判断左括号和右括号的数量是否一致且每个右括号都有一个左括号与之对应。

思路:

这种题目时间复杂度为O(n),空间复杂度为O(1),具体的做法是,我们可以设置一个变量num用来表示“(”,“)”数量的差值,当我们遍历字符串的时候,遇到左括号则num++,遇到右括号则num--;在我们遍历的过程中,如果出现num<0的情况(表示右括号比左括号多,也就是出现“)(”这种情况),则返回false,如果没有则继续遍历,直到遍历完毕。如果num==0,那么返回true,否则返回false;

代码举例:

import java.util.*;

public class Parenthesis {
    public boolean chkParenthesis(String A, int n) {
        // write code here
        //转换字符串为数组
        char[] chs = A.toCharArray();
        //设置参数表示左右括号差值
        int num = 0;
        for(int i=0;i<n;i++){
            if(chs[i] == '('){
                num++;
            }else if(chs[i] == ')'){
                num--;
            }else if(num<0){
                return false;
            }
        }
        if(num != 0){
            return false;
        }
        return true;
    }
}

三、最长无重复字符子串

题型:

给定一个字符串str,返回str的最长无重复字符子串的长度

例如:“abcd”的最长无重复字符子串的长度为4,而“abcb”的最长无重复字符子串的长度为3;

思路:

这种题目的最优解时间复杂度为O(n),空间复杂度为O(n)。

那么这道题的思路是,我们需要遍历这个字符串数组,通过创建一个hash表来统计每一种字符之前出现的位置,如果当前位置为i,那么它前面一个位置为i-1,创建一个整型变量pre,代表以s[i-1]结尾的情况下,最长无重复子串的起始坐标。拥有这两个变量,首先我们从hash表中取出当前位置字符上一次出现的位置,这个位置后面一个位置我们表示为位置A,然后从pre中得到以s[i-1]结尾的情况下,最长无重复子串的长度,我们把这个位置记为位置B,如图:

如果位置B在位置A的右边,那么以S[i]位置字符结尾的最长无重复子串的长度为S[i]到位置B的距离,同理如果B在A的左边,那么位置A到S[i]的距离就是以S[i]位置字符结尾的最长无重复子串的长度。

代码举例:

import java.util.*;

public class DistinctSubstring {
    public int longestSubstring(String A, int n) {
        // write code here
        if (A == null || n == 0) {
            return 0;
        }
        char[] chas = A.toCharArray();
        //创建hash表并赋初值
        int[] map = new int[256];
        for (int i = 0; i < 256; i++) {
            map[i] = -1;
        }
        //创建pre变量
        int pre = -1;
        //创建变量表示最终结果
        int len = 0;
        //创建变量表示B位置的坐标
        int cur = 0;
        //遍历字符串
        for(int i=0;i<n;i++){
            //找到A位置和B位置,比较,大的说明在右边
            pre = Math.max(pre, map[chas[i]]);
            //得到当前坐标字符的最长无重复子串长度
            cur = i - pre;
            //更新变量
            len = Math.max(len, cur);
            map[chas[i]] = i;
        }
        return len;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36125072/article/details/81706428