面试复习-------算法与数据结构------字符串

(1)数组排成最小的数(剑指offer33/leetcode179

解题思路:关于数字的大数问题最终都要转换成字符串解决。在该题中,将vector 转换成vector,然后调用sort函数,需要定义sort第三个规则如下:

 static bool cmp(const string str1, const string str2){
            string s1 = str1 + str2;
            string s2 = str2 + str1;
            if(s1.compare(s2)>0)
                return true;
            else 
                return false;
        }

就可以将字符串数组进行排序,然后依次相连接即可。


(2)哈希表的使用(剑指offer35、55,leetcode242

使用场景:当顺序遍历一个string,其中一次字符遍历可能会用到之前字符遍历结果的时候,就可以使用哈希表(如果不使用哈希表,可能就需要双重遍历);

-------int hashtable[256],手动构造(字符ASCII值为索引,字符在字符串中索引或者count次数为值)

-------unordered_map库函数的使用。


(3)字符串的简单操作(插入、删除字符,旋转)

插入删除的时候,为了避免多次移动,可以采用“倒着”复制的技巧(剑指offer4):先遍历一遍字符串,统计总共需要

增加的次数,然后从末尾处开始向前进行操作;

字符串的翻转(库中有reverse方法,传入begin()与end()两个迭代器)

变形:单词翻转,左旋字符串(剑指offer42

“I am a student”------->"student a am I"

解题思路:①先翻转整个字符串,变成"tneduts a ma I"

②然后翻转每一个空格符号间隔开的单词

"abcdefg"----2---->"cdefgab"

解题思路:①先分成两部分旋转字符串,变成"ba|gfedc"

②然后将整个字符串旋转


(4)字符串的匹配

正则表达式匹配(剑指offer53

递归的使用;

需要考虑清楚当后一个pattern为'*'时该如何匹配;代码如下:

bool match(const string pattern,const string str,int pattern_begin,int str_begin)
{
    if(pattern_begin==pattern.length() && str_begin==str.length())
        return true;
    if(pattern_begin==pattern.length() && str_begin!=str.length())
        return false;
    if(pattern_begin!=pattern.length() && str_begin==str.length() && pattern.at(pattern_begin)!='*')
        return false;
    if(pattern_begin!=pattern.length() && str_begin==str.length() && pattern.at(pattern_begin)=='*')
        return true;
    if(pattern_begin!=pattern.length()-1 && pattern.at(pattern_begin+1)=='*')
    {
        if(pattern.at(pattern_begin)==str.at(str_begin))
            return match(pattern,str,pattern_begin+2,str_begin+1) ||
                   match(pattern,str,pattern_begin,str_begin+1) ||
                   match(pattern,str,pattern_begin+2,str_begin);
        else if(pattern.at(pattern_begin)=='.' && str_begin!=str.length())
            return match(pattern,str,pattern_begin+2,str_begin+1) ||
                   match(pattern,str,pattern_begin,str_begin+1) ||
                   match(pattern,str,pattern_begin+2,str_begin);

        else
            return match(pattern,str,pattern_begin+2,str_begin);
    }
    else if(pattern.at(pattern_begin)==str.at(str_begin)
            ||pattern.at(pattern_begin)=='.' && str_begin!=str.length())
            return match(pattern,str,pattern_begin+1,str_begin+1);
    else
        return false;
}


表示数值的字符串( 剑指offer54

需要考虑清楚:第一个字符为正负号、小数点、e或者E

//判断剩余的部分是不是科学计数法
bool isExponential(char** string)
{
    if(**string != 'e' && **string != 'E')
        return false;
    (*string)++;
    if(**string == '+' || **string == '-')
        (*string)++;
    if(**string == '\0')
        return false;
    while(**string != '\0' && **string >= '0' && **string <= '9')
        (*string)++;
    return (**string == '\0')?true:false;
}


bool isNumber(char* string)
{
    if(string==NULL)
        return false;
    if(*string == '+' || *string == '-')
        string++;
    if(*string == '\0')
        return false;

    bool num = true;
    while(*string != '\0' && *string >= '0' && *string <= '9')
        string++;
    if(*string != '\0')
    {
        if(*string == '.')
        {
            string++;
            while(*string != '\0' && *string >= '0' && *string <= '9')
                string++;
            if(*string == 'e' || *string == 'E')
                num=isExponential(&string);
        }
        else if(*string == 'e' || *string == 'E')
            num = isExponential(&string);
        else
            num=false;
    }
    return num&&(*string == '\0');
}

(5)数字运算,大数加法和二进制加法

打印1到最大n位数(剑指offer12

解题思路:用一个字符串表示一个大数,分别实现increase(模拟数字++),is_max(是否已经到达最大),print

代码如下:

bool is_max(char* str, int n)
{
    int count = 0;
    while(str[count]=='9')
        count++;
    if(count==n)
        return true;
    else
        return false;
}

void incre(char* str,int n)
{
    int token=n-1;
    for(int i=n-1;i>=0;i--)
    {
        if(token==i && str[i]=='9')
        {
            str[i]='0';
            token--;
        }
        else if(token==i)
        {
            str[i]++;
            break;
        }
    }
}

void print(char* str,int n)
{
    bool first0 = false;
    for(int i=0;i

(6)字符串的排列组合(剑指offer28

可以采用回溯的思想,将第一个字符分别与后面的字符进行替代,然后递归,代码如下:

void arrange(string str, int index)
{
    if(index == str.length()-1)
        cout << str << endl;
    else{
        for(int i = index; i < str.length(); ++i){
            swap(str.at(index), str.at(i));

            arrange(str, index+1);

            swap(str.at(index), str.at(i));
        }
    }
}

如果是求字符串的组合问题:

abc的排列有:abc、acb、bac、bca、cab、cba

abc的组合有:a、b、c、ab、ac、bc、abc

同样也是采用回溯的解法:依次求出长度为1,2,....,n的组合

n个字符长度为m的组合问题可以转换为n-1中长度为m-1 和 n-1长度为m

string result;
void combination(const string str)
{
    if(str.empty())
        return;
    for(int i = 1; i <= str.length(); ++i){
        combinationCore(str, i, 0);
    }
}

void combinationCore(const string str, int m, int index)
{
    if(m > str.length()-index)
        return;
    if(m == 0){
        cout << result <
结论:排列组合问题都可以采用回溯法解决


(7)求字符串最长回文子串(leetcode 5

解题思路:分别统计以每一个字符为中心的奇偶回文子串长度,记录其中的最大值以及中心点;


(8)按之字形排列字符串(leetcode6

解题思路:声明一个vector的数组,大小为给定行数,维护一个行数字,每次使数组中不同的string加字符。


(9)求字符串数组前缀(leetcode14

解题思路:先对数组进行排序,然后就只需要看第一个和最后一个字符串;


(10)九键输入法转换(leetcode17

解题思路:构造常量数组 const vector mapping{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

采用回溯法。

(11)括号匹配(leetcode20

解题思路:括号匹配的题目都可以用栈来解决。


(12)括号排列(Leetcode22

解题思路:动态规划


你可能感兴趣的:(算法与数据结构)