经典算法面试题目:Cracking the coding interview–Q1.1

题目:

Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structures?

实现一个算法来判断一个字符串中的字符是否唯一(即没有重复).不能使用额外的数据结构。 (即只使用基本的数据结构)

解答:

首先,你可以问面试官,构成字符串的字符集有多大?是ASCII字符,还是只是26个字母? 还是有更大的字符集,对于不同的情况,我们可能会有不同的解决方案。

如果我们假设字符集是ASCII字符,那么我们可以开一个大小为256的bool数组来表征每个字 符的出现。数组初始化为false,遍历一遍字符串中的字符,当bool数组对应位置的值为真, 表明该字符在之前已经出现过,即可得出该字符串中有重复字符。否则将该位置的bool数组 值置为true。代码如下:

bool isUnique1(string s)
{
    bool a[256];
    memset(a, 0, sizeof(a));
    int len = s.length();
    for(int i=0; i < len; ++i)
    {
        int v = (int)s[i];
        if(a[v]) return false;
        a[v] = true;
    }
    return true;
}

该算法的时间复杂度为O(n)。我们还可以通过位运算来减少空间的使用量。 用每一位表征相应位置字符的出现。对于ASCII字符,我们需要256位,即一个长度为8的int 数组a即可。这里的关键是要把字符对应的数字,映射到正确的位上去。比如字符’b’对应的 代码是98,那么我们应该将数组中的哪一位置为1呢?用98除以32,得到对应数组a的下标: 3。98对32取模得到相应的位:2。相应代码如下:

bool isUnique2(string s)
{
    int a[8];
    memset(a, 0, sizeof(a));
    int len = s.length();
    for(int i=0; i < len; ++i)
    {
        int v = (int)s[i];
        int idx = v/32, shift=v%32;

        if(a[idx] & (1 << shift)) return false;//<<左移不改变原来的数值。移位的结果是:第一个操作数乘以2的幂,指数的值是由第二个数给出的。
        //右边空出用0填补.在不溢出的情况下,每左移一位相当于乘以2
        a[idx] |= (1 << shift);
        //只要没有出现重复的,a[idx]是会从0开始一直加下去的,a[idx] & (1 << shift)一直会是0,从0加到2的31次方,接下来就是a[idx+1]的了。我是差不多这样理解的。
    }
    return true;
}

两个算法的本质其实是一样的,只不过一个用bool单元来表征字符出现,一个用位来表征。

完整代码如下:

#include <iostream>
#include <cstring>
using namespace std;

bool isUnique1(string s)
{
    bool a[256];
    memset(a, 0, sizeof(a));
    int len = s.length();
    for(int i=0; i < len; ++i)
    {
        int v = (int)s[i];
        if(a[v]) return false;
        a[v] = true;
    }
    return true;
}

bool isUnique2(string s)
{
    int a[8];
    memset(a, 0, sizeof(a));
    int len = s.length();
    for(int i=0; i < len; ++i)
    {
        int v = (int)s[i];
        int idx = v/32, shift=v%32;
        if(a[idx] & (1 << shift)) return false;
        a[idx] |= (1 << shift);
    }
    return true;
}
int main()
{
    string s1 = "i am hawstein.";
    string s2 = "abcdefghijklmnopqrstuvwxyzABCD1234567890";
    cout << isUnique1(s1) << " " << isUnique1(s2) << endl;
    cout << isUnique2(s1) << " " << isUnique2(s2) << endl;
    return 0;
}

如果字符集只是a-z(或是A-Z),那就更好办了,用位运算只需要一个整型数即可。

bool isUnique3(string s)
{
    int check = 0;
    int len = s.length();
    for(int i=0; i < len; ++i)
    {
        int v = (int)(s[i]-‘a‘);
        if(check & (1 << v)) return false;
        check |= (1 << v);
    }
    return true;
}
时间: 2024-11-01 21:44:30

经典算法面试题目:Cracking the coding interview–Q1.1的相关文章

Cracking the Coding Interview Q1.8

Assume you have a method isSubstring which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring ( i.e., “waterbottle” is a rotation of “erbottlewa

Cracking the Coding Interview Q1.6

Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees. Can you do this in place? 思路:从最晚层向内,一层一层交换. public static void rotate(int[][] matrix, int n) { for (int layer = 0

Cracking the Coding Interview Q1.7

Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0. 见leetcode Set Matrix Zeroes Cracking the Coding Interview Q1.7,布布扣,bubuko.com

经典算法面试题目---1.3

题目 Design an algorithm and write code to remove the duplicate characters in a string without using any additional buffer. NOTE: One or two additional variables are fine. An extra copy of the array is not. FOLLOW UP Write the test cases for this metho

经典算法面试题目-判断s2是否是s1的旋转字符串(1.8)

题目 Assume you have a method isSubstring which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring ( i.e., "waterbottle" is a rotation of &qu

经典算法面试题目(1.7)

题目 Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0. 写一个函数处理一个MxN的矩阵,如果矩阵中某个元素为0,那么把它所在的行和列都置为0. 解答 简单题.遍历一次矩阵,当遇到元素等于0时,记录下这个元素对应的行和列. 可以开一个行数组row和列数组col,当元素a[i][j]等于0时, 就把row[i]和col[j]置为1. 第二次遍

经典算法面试题目(1.6)

题目 Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees. Can you do this in place? 一张图像表示成NxN的矩阵,图像中每个像素是4个字节,写一个函数把图像旋转90度. 你能原地进行操作吗?(即不开辟额外的存储空间) 解答 我们假设要将图像逆时针旋转90

《Cracking the Coding Interview》——第16章:线程与锁——题目3

2014-04-27 19:26 题目:哲学家吃饭问题,死锁问题经典模型(专门用来黑哲学家的?). 解法:死锁四条件:1. 资源互斥.2. 请求保持.3. 非抢占.4. 循环等待.所以,某砖家拿起一只筷子后如果发现没有另一只了,就必须把手里这只筷子放下,这应该是通过破坏"请求保持"原则来防止死锁产生,请求资源失败时,连自己的资源也进一步释放,然后在下一轮里继续请求,直到成功执行. 代码: 1 // This is the class for chopsticks. 2 import j

《Cracking the Coding Interview》——第18章:难题——题目13

2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3)级别的时间和空间进行动态规划.这道题目和第17章的最后一题很像,由于这题的时间复杂度实在是高,我动手写了字典树进行加速.如果单纯用哈希表来作为词典,查询效率实际会达到O(n)级别,导致最终的算法复杂度为O(n^4).用字典树则可以加速到O(n^3),因为对于一个字符串"abcd",只需要