Cracking the Coding Interview 第一章

第一章:数组与字符串

1 数组与字符串

请实现一个算法,确定一个字符串的所有字符是否全都不同。这里我们要求不允许使用额外的存储结构。
给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,False代表存在相同的字符。保证字符串中的字符为ASCII字符。字符串的长度小于等于3000。
测试样例:
"aeiou"
返回:True
"BarackObama"
返回:False
View Code

思路:(1) 两个for循环,比较后面的是否相同 O(n2), O(1)。

  (2) hash 建个boolean数组,为true, return false。 问题:ascii : 长度应为 256,而不是26。  

import java.util.*;

public class Different {
    public boolean checkDifferent(String iniString) {
        // write code here
        booelan [] hash = new boolean [256];
        for (int i = 0; i < iniString.length(); i++){
            int val = iniString.charAt(i);
            if (charset[val]){ //error: if followed by whitespace, charset[val]==true
                return false;
            }
            charset[val] = true;
        }
        return true;
    }
}
View Code

6 旋转矩阵

有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时针旋转90度。
给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于500,图像元素小于等于256。
测试样例:
[[1,2,3],[4,5,6],[7,8,9]],3
返回:[[7,4,1],[8,5,2],[9,6,3]]
View Code

思路: 找规律,以中心为原点进行坐标变换,从最外面那层往中间(error:注意每层处理的元素,即i,j 迭代的范围不要多处理)

 1 import java.util.*;
 2 
 3 public class Transform {
 4     public int[][] transformImage(int[][] mat, int n) {
 5         // write code here
 6         for (int i = 0; i < n / 2; i++){
 7             for (int j = i; j < n - 1 - i; j++){
 8                 int temp = mat[i][j];
 9                 mat[i][j] = mat[n - 1 - j][i];
10                 mat[n - 1 - j][i] = mat[n - 1 - i][n - 1 - j];
11                 mat[n - 1 - i][n - 1 - j] = mat[j][n - 1 - i];
12                 mat[j][n - 1 - i] = temp;
13             }
14         }
15         return mat;
16     }
17 }
View Code

7 清除行列

题目描述
请编写一个算法,若N阶方阵中某个元素为0,则将其所在的行与列清零。
给定一个N阶方阵int[][](C++中为vector>)mat和矩阵的阶数n,请返回完成操作后的int[][]方阵(C++中为vector>),保证n小于等于300,矩阵中的元素为int范围内。
测试样例:
[[1,2,3],[0,1,2],[0,0,1]]
返回:[[0,0,3],[0,0,0],[0,0,0]]
View Code

思路:用boolean数组标记每行或每列是否需要清除,最后统一处理。(不能边判断边处理,因为这会影响该行或列还没扫到的元素,从而使整个矩阵全部为0)

 1 import java.util.*;
 2 
 3 public class Clearer {
 4     public int[][] clearZero(int[][] mat, int n) {
 5         // write code here
 6         boolean [] zeroRow = new boolean [n];
 7         boolean [] zeroCol = new boolean [n];
 8         for (int i = 0; i < n; i++){
 9             for (int j = 0; j < n; j++){
10                 if (mat[i][j] == 0){
11                     zeroCol[j] = true;
12                     zeroRow[i] = true;
13                 }
14             }
15         }
16         for (int i = 0; i < n; i++){
17             for (int j = 0; j < n; j++){
18                 if (! zeroRow[i] || zeroCol[j]){
19                     mat[i][j] = 0;
20                 }
21             }
22         }
23         return mat;
24     }
25 }
View Code

8 翻转子串

题目描述
假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串。请将这个算法编写成一个函数,给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成,要求只能调用一次检查子串的函数。
给定两个字符串s1,s2,请返回bool值代表s2是否由s1旋转而成。字符串中字符为英文字母和空格,区分大小写,字符串长度小于等于1000。
测试样例:
"Hello world","worldhello "
返回:false
"waterbottle","erbottlewat"
返回:true
View Code

思路: s1的旋转串一定是s1 + s1 的子串。(为自己的机智点赞)。

1 import java.util.*;
2 
3 public class ReverseEqual {
4     public boolean checkReverseEqual(String s1, String s2) {
5         // write code here
6         String doubleS1 = s1 + s1;
7         return doubleS1.contains(s2);
8     }
9 }
View Code

 

posted @ 2016-11-27 18:37  hxidkd  阅读(200)  评论(0编辑  收藏  举报