哈希表
While not all problems can be solved with hash tables, a shocking number of interview problems can be Before your interview, make sure to practice both using and implementinghash tables
尽管哈希表不能解决所有的问题,但是面试中的大部分问题能用它解决。在面试之前一定要好好准备下哈希表的使用和实现。
1 public HashMap buildMap(Student[] students) {2 HashMap map = new HashMap();3 for (Student s : students) map.put(s.getId(), s);4 return map;5 }
ArrayList (Dynamically Resizing Array):
数组链表
An ArrayList, or a dynamically resizing array, is an array that resizes itself as needed whilestill providing O(1) access A typical implementation is that when a vector is full, the arraydoubles in size Each doubling takes O(n) time, but happens so rarely that its amortized timeis still O(1)
数 组链表(大小可动态变化的数组)在使用中能够根据需要扩大数组的容量,并且能够提供O(1)的随机访问效率。数组链表典型的一种实现方法就是:当达到数组 上限,就将数组容量扩大一倍。虽然在扩大容量时候的时间复杂度为O(n),但是这样情况都较少发生,所以总的时间开销可近似为O(1)。
1 public ArrayList merge(String[] words, String[] more) {2 ArrayList sentence = new ArrayList();3 for (String w : words) sentence.add(w);4 for (String w : more) sentence.add(w);5 return sentence;6 }
StringBuffer / StringBuilder
字符串
Question: What is the running time of this code?
1 public String makeSentence(String[] words) {2 StringBuffer sentence =
new StringBuffer();3 for (String w : words) sentence.append(w);4 return
sentence.toString();5 }
问:下面这段代码的时间复杂度?
Answer:
O(n^2), where n is the number of letters in sentence Here’s why: each
time youappend a string to sentence, you create a copy of sentence and
run through all the letters insentence to copy them over If you have to
iterate through up to n characters each time in the loop, and you’re
looping at least n times, that gives you an O(n^2) run time Ouch! With
StringBuffer (or StringBuilder) can help you avoid this problem 1 public
String makeSentence(String[] words) {2 StringBuffer sentence = new
StringBuffer();3 for (String w : words) sentence.append(w);4 return
sentence.toString();5 }
答:O(n^2),
这里的n为字符串sentence中的字符的个数。理由如下:每次你在向字符串sentence串中才追加一个数组的时候,就需要重新复制一次
sentence中的字符,每次复制都需要从头到尾遍历一次sentence。这样的话把所有的单词追加到sentence中的时间复杂度为
O(n^2)。
1.1
Implement an algorithm to determine if a string has all unique
characters What if you can not use additional data structures?
For
simplicity, assume char set is ASCII (if not, we need to increase the
storage size The rest of the logic would be the same) NOTE: This is a
great thing to point out to your interviewer!
1 public static boolean isUniqueChars2(String str) {
2 boolean[] char_set = new boolean[256];
3 for (int i = 0; i < str.length(); i++) {
4 int val = str.charAt(i);
5 if (char_set[val]) return false;
6 char_set[val] = true;
7 }
8 return true;
9 }
We can reduce our space usage a little bit by using a bit vector We
will assume, in the below code, that the string is only lower case ‘a’
through ‘z’ This will allow us to use just a single int
Alternatively, we could do the following:
1 Check every char of the string with every other char of the string
for duplicate occurrences This will take O(n^2) time and no space
2
If we are allowed to destroy the input string, we could sort the string
in O(n log n) time and then linearly check the string for neighboring
characters that are identical Careful, though - many sorting algorithms
take up extra space
1.1 设计算法判断一个字符串中字符都是否唯一的。如果不能使用额外的数据结构呢?
解答1.1:先假设字符串中的字符均为ASCII码(如果不是的可以增大存储空间,而算法的逻辑是相同的)。“假设”在你的面试中非常的重要。
算法的时间空间复杂度均为O(n),n为字符串的长度。
采用bit序列来代替数组可以为我们进一步节省空间。这里我们需要假设字符串中的字符为'a'-'z'。这样只要用一个int型的变量就能记录字符是否出现了。
本题还有其他的解法:
1. 检查每一个字符在字符串中的出现次数,这样的方法时间复杂度为O(n^2),但是空间复杂度为0。
2. 如果字符串中的内容可以破坏的话。我们可以将字符串中的字符排序(时间复杂度为O(nlogn)),然后遍历字符串中的某个字符相邻的字符时候相同。但是要注意有些排序算法是需要额外的存储空间的。
1.2
Write code to reverse a C-Style String (C-String means that “abcd” is
represented as five characters, including the null character )SOLUTION
:This is a classic interview question The only “gotcha” is to try to do
it in place, and to be care- ful for the null character 1 void
reverse(char *str) { 2 char * end = str; 3 char tmp;
4 if (str) { 5 while (*end) {
6 ++end; 7 } 8 --end;
9 while (str < end) { 10 tmp =
*str; 11 *str++ = *end; 12 *end-- =
tmp; 13 } 14 } 15 }
1.2 实现C语言风格的字符串反转的算法
(C语言字符串:例如“abcd”字符串为5个字符,最后一个字符为/0用来表示字符串结束。)
解答1.2:
这个是面试的常见问题。如果你说你懂的话,就马上开始写代码吧。
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 notFOLLOW
UPWrite the test cases for this method
1.3 设计一个算法移除字符串中的重复字符,算法不使用额外缓冲。并对你的算法设计测试用例。注意:一两个变量使用当是OK的,但是复制整个数组就不行了。
解答1.3:
无字符串缓冲算法
1. 对每个字符判断是否为重复字符。
2. 重复字符直接跳过,非重复字符记录。
时间复杂度为O(n^2)
测试用例:
1. 无重复字符:abcd;
2. 全重复字符:aaaa;
3. 无效字符串:null;
4. 连续重复字符串:aaaabbbb;
5. 非连续重复字符串:abcabc;
字符串缓冲算法:
1. 无重复字符:abcd;
2. 全重复字符:aaaa;
3. 无效字符串:null;
4. 空字符串:empty
5. 连续重复字符串:aaaabbbb;
6. 非连续重复字符串:abcabc;
1.4 Write a method to decide if two strings are anagrams or not
1.4 写一个函数判断两个字符串是否使用相同的字符构成。
解答1.4:
本题有两种解法
法1 排序法
法2 计数法
1.5 Write a method to replace all spaces in a string with ‘%20’
1.5 编写代码将字符串在中的空格替换为‘%20’
解答1.5:
算法流程:
1 遍历字符串,记录下有多少个空格;
2 从字符串尾部重新解析:
(1) 如果当前字符为空格,在写入字符串'%20'
(2) 非空格则直接记录。
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?
1.6 给出一张图片,表示为NXN的居然,每个像素点为4字节。写一个函数实现将这张图片旋转90°。
解答1.6:
图片的旋转可以将像素划分成一圈一圈,然后从最外层一圈一圈上来旋转。旋转某一圈的某个元素的时候,相当于对应的上下左右依次交换。
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
1.7 实现算法:在一个MxN的矩阵中,如果某一元素为0,则将其所在的行和列都置为零。
解答1.7:
乍一看题目,先遍历矩阵,出现0元素,就将所在的行列置零。但是这样的方法执行下来的话整个矩阵都变成了0了。
一个变通的方法,在另外一个MxN的矩阵中记录是否出现零的情况,然后根据记录对原来的矩阵中对相应的行列进行置零。可是这样方法的空间复杂度为O(MxN)。有没有改进的空间呢?
经过观察,其实我们只需要记录哪一列和哪一行需要置零即可。那么我们新的记录方法即为:使用两个数组rows[]和col[]来记录需要置零的行列。更具这样的方法算法代码如下:
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 “erbottlewat”)
1.8 假设你已经有一个函数用来 isSubstring(s1,s2) 用来判断字符串s1是否是字符串s2的子串。那么现在给你一个字符串s1和s2,让你判断s1是否是s2循环位移得到的。你的算法中只能调用一次isSubstring (比如“waterbottle”循环位移就可以得到"erbottlewat")。
解答1.8:
算法描述:
1 如果length(s1)!= length(s2) 返回 false
2 将是s1和本身连接,得到新字符串s1',调用isSubstring(s2,s1')判断s2是否为s1'的字符串。