Cracking the Code Interview Chapter One-- TaylorZhangYuxin's Solusion

来源:互联网 发布:sql server2008r2下载 编辑:程序博客网 时间:2024/06/06 11:39

This article is my own thinking and analysis when reading the cracking the code interview 6th edition.

My Life For A better Life

Chapter 1 Arrays and Strings

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

Analysis:

The key to solve this question is to find out the duplicate characters in the string. Once there is one duplicate character, the string is not unique.
The other approach is that, find out the total number of characters. For example, if the total data base for characters is 26 English letters, then if the string’s length is longer than 26, there must be duplicate characters in the string. The result that the string is not a unique string has reached.

Solution description:

(1) Use data structures.
Use a hash table to hold all the characters. Add all characters into hash table. Before add every character, check whether there is the same character in the hash table. Loop through all the characters in the string until the end of the string (is unique) or the method that find the duplicate characters returns true (not unique).

private boolean isUnique01(long max, String source) {    long strLength = source.length();    if(strLength > max) return false;    HashSet<Character> data = new HashSet<Character>();    for(int i = 0; i < strLength ; i++){        char tempChar = source.charAt(i);        if(data.contains(tempChar)) return false;        else{            data.add(tempChar);        }    }    return true;}

(2) No data structure.
The characters are comparable. This question is more like, if I have a group of numbers, how can you tell these numbers are unique. The solution is that sort the numbers in to the array. Sorting and comparing until there is one duplicate numbers in the array (not unique) or reach the very last number (unique).

private boolean isUnique02(long max, String src) {    int strLength = src.length();    if(strLength == 1) return true;    if(strLength > max) return false;    //sort every character into one array    char[] pool = src.toCharArray();    java.util.Arrays.sort(pool);    boolean duplicate = false;    for(int i = 0; i < strLength ; i++){        if(i+1 == strLength || pool[i] != pool[i+1] ){}        else{            return false;        }    }    return true;}

(3) Standard solution
Based on the total data base, create an array of Boolean that holds all the characters. Check every character in the string to match the index of the array. Once a new character was found, set false to true. Once the matched index gives a true, break and return false to indicate that this is a duplicate character.

(4) There is a better way to reduce the space usage by using a bit vector to replace the Boolean array. (Assumption: the string only uses the lower case letters ‘a’ to ‘z’).

private boolean isUniqueChars(String str){    int checker = 0;    for(int i = 0; i < str.length(); i++){        int val = str.charAt(i)- 'a';        if((checker & (1 << val)) > 0)){            return false;        }        checker |= (1 << val);    }    return true;}

What I got:

(1) Not just focus the data itself. If some data has some specialties, like appear fixed certain of times, check that data first or think about that approach first to get a better algorithm.
Sometimes, this is a gate to a short way.
(2) Somethings, a Boolean array and be replaced by a bit vector.

1.2 Give two strings, write a method to decide if one is the permutation of the another.

Analysis:

Permutation means any combination with the same letters collection. It has two basic characters. One is that, length of the string must be the same. The second one is that, the number of each type of letters must be the same between the two strings.
So, the first step is checking the length of each string. If the same, go to next step. If not, break and return false.
The second is coming up a way to check that whether the character collection is the same for the two string.

Solution description:

(1) Create two array of integer, set value as 0, based on the size of character data base. Use the value for character as the index. Count the number of each characters for both string in to array. Compare the array, if the same, then the two strings are permutation.

private boolean checkPermutation01(int size, String src1, String src2) {            int size1 = src1.length();    int size2 = src2.length();    if(size1 != size2) return false; //check if the same size    int[] collection01 = new int[size];    int[] collection02 = new int[size];    for(int i = 0; i<size1; i++){        collection01[src1.charAt(i)] +=1 ;        collection02[src2.charAt(i)] +=1 ;              }    for(int i = 0; i<size; i++){        if(collection01[i]!=collection02[i]){            return false;        }    }    return true;}

(2) Create one array of integer, set value as 0, based on the size of character data base. Count each character in the first string with corresponding value as the index of the array, increment by one. Then, for the second string, count each character in the array by decrement by 1. At last, check all the elements in the array. If they are all 0, the two are permutation. Otherwise, not.

private boolean checkPermutation02(int size, String src1, String src2) {    int size1 = src1.length();    int size2 = src2.length();    if(size1 != size2) return false; //check if the same size    int[] collection01 = new int[size];    for(int i = 0; i<size1; i++){        collection01[src1.charAt(i)] +=1 ;        collection01[src2.charAt(i)] -=1 ;    }    for(int i = 0; i<size; i++){        if(collection01[i]!=0){            return false;        }    }    return true;}

(3) Solution from the book.
Book uses a java method that comes from java.util.Arrays.sort() to sort an array of character that converted from two String. After sorting, create two arrays based the result and compare them. Equals means true, otherwise not. This solution is not more optimal than MY solution above. However, it’s another approach.

/** * This solusion is a standard solution one in the book.  * Use sorting to complete the comparison. *  * @param size * @param src1 * @param src2 * @return */private boolean checkPermutation03(int size, String src1, String src2) {    int size1 = src1.length();    int size2 = src2.length();    if(size1 != size2) return false; //check if the same size    char[] tempCharArray1 = {'1','2','4','4','4','5','d'};    char[] tempCharArray2 = src2.toCharArray();    java.util.Arrays.sort(tempCharArray1);    java.util.Arrays.sort(tempCharArray2);    String sorting01 = new String(tempCharArray1);    String sorting02 = new String(tempCharArray2);    return sorting01.equals(sorting02);}

What I got.

(1) There was an existing method to sort array, in java.util.Array.sort(), which can be used directly to sort the array.
(2) It is able to create new String based on a character array. Like

char[] arrayChar = [“this is a new array of characters”];
String newString = new String(arrayChar);

1.3 Write a method to replace all spaces in a string with ‘%20’. You may assume that the string has sufficient space at the end to hold the additional characters, and that you are given the “true” length of the string.

input: “Mr John Smith    ”, 13output: ”Mr%20John%20Smith”

Analysis

This is a quite simple question. The true length of the string can help us target the space that need to be processed. And the sting which has sufficient space do not need to resize but just fill in “%20”. One more thing need to be considered is that, what if multiple spaces between two letters, whether to replace it with one “%20” or multiple “%20”?
Additional requirement, in Java, use character array.

Solution description:

Case 1: Each space replaces with one %20.
(1) Create a new array of characters with the length of given string. Use a counter to iterate through the string. Once the character is space, replace it with ‘%’’2’’0’ into the array. Otherwise, just copy the character into the array.

private String convert01(String content, char[] charArray) {    int i = 0;    int j = 0;    for(i=0; i<content.length(); i++){        char temp = content.charAt(i);        if(temp ==' '){            charArray[j] = '%';            j++;            charArray[j] = '2';            j++;            charArray[j] = '0';            j++;        }        else{            charArray[j] = temp;            j++;        }    }    return new String(charArray);}

(2) less optimal one. Convert the string into one array of character. Iterate through the array, once a space was found, “%20” was added into the array and all the characters was moved back in 3 steps.

private String convert02(String content, char[] charArray, int srcLength) {    // TODO Auto-generated method stub    int i = 0;    int j = 0;    charArray = content.toCharArray();    for(i = 0; i< srcLength; i++){        if(charArray[i]==' '){            //move all things backwords            for(int k=srcLength-1; k>i; k--){                charArray[k] = charArray[k-2];            }            //fill in "%20"            charArray[i] = '%';            i++;            charArray[i] = '2';            i++;            charArray[i] = '0';        }    }    return new String(charArray);}

(3) Solution from the book. It uses a reverse order that iterate from the end of the array to the beginning to refill the array with new characters. The main reason to work in this way is that it did not use a new empty array to hold the characters. It just overwrites the original array, from the end to the beginning.

/** * The thought of the solution from the book. Its initialization is different from my solusion. *  * @param length the true content length * @param charArray an array as teh input that holds the original string * @return */private String convert03(int length, char[] charArray) {    //first determine how long is the final array    int spaceNum = 0;    for(int i = 0; i < length; i++){        if(charArray[i] == ' '){            spaceNum++;        }    }    //set the array end    int endpoint = length + 2*spaceNum;    charArray[endpoint] = '\0';    //iterate through the array from end to beginning to overwrite the array    for(int j = length - 1; j>0; j--){        if(charArray[j] == ' '){            charArray[endpoint-1] = '0';            charArray[endpoint-2] = '2';            charArray[endpoint-3] = '%';            endpoint -= 3;        }        else{            charArray[endpoint-1] = charArray[j];            endpoint -= 1;        }    }    return new String(charArray);}

Case 2: Only one “%20” can be filled between two letters no matter how many spaces are there.

Example:
“This is an example” -> This%20is%20an%20example”.

This situation requires a buffer to store the previous letter. This buffer will set to 1 when a space is met. Then only when the next letter is not space and the buffer is 1, one “%20” can be added into the string.

What I got:

(1) Before the beginning, make it clear that must we edit the original array or it is allowed that we can create a new array to process.
(2) when facing the overwrite situation, start from the end to avoid overwriting the useful data.

1.4 [GOOD QUESTION] Palindrome Permutation: Given a string, write a function to check if it is a permutation of a palindrome. A palindrome is a word or phrase that is the same forwards and backwards. A permutation is a rearrangement of letters. The palindrome does not nedd to be limited to just dictionary words.

Example: input: tact coa. output: true(“ta cocat”, ”atcoct a”).

Analysis:

This question has two key features.
One is palindrome. This requires the letter that was read the same from back to the front and from the front to the end. There are two situations. One is the odd number of meaningful characters. Here the meaningful character means the letters in the ASCII table but not space(‘’). The other case is that the number of characters is even.
The other feature is permutation. A Permutation means all possibilities of the arrangement of the letters. So what matters now is the number of each kind of letters.
The odd number of letters:
In this situation, if the permutation wants to be a palindrome, there must be one and only one kind of letter is of an odd number. Because there must be one and only one letter in the middle. If more than one letter is odd or no odd letter count, this must not be a palindrome. So now, here are three steps. 1. Iterate through the string to count all the characters but filter all the spaces. 2. Check the result. There is only one letter that is of odd number. 3. All the other kind of letters are of the even number. If one string meets all the three rules above, it’s permutation must be a palindrome. Otherwise not.
The even number of letters:
In this situation, all the letters must be of the even number. As well, iterate through the string to count the number of each letters. Only when all the letters are even number, it’s permutation is palindrome.

Solution description:

(1) Sorting. Convert the String into an array of character. Sort this array so that all the letters are in order. Check from the beginning to the end while ignoring the spaces. Because in the array, the same letter will be placed next to each other, so it’s easy to count the number for each kind of letters. Set a counter to count how many kinds of letters are in the odd number, named “kinds”. Once this counter reaches 2, break and return false. Set another counter to count the total number of letters, named “total”. If at the end, “total” is an even, while the “kinds” is 0, or “total” is an odd, while the “kinds” is 1, returns true. Otherwise, return false.

private boolean solution1(String input) {    // TODO Auto-generated method stub    char[] characters = input.toCharArray();    java.util.Arrays.sort(characters);    //iterate through the array to check it    int oddcounter = 0;    int lettercounter = 0;    int tempcounter = 0;    char letterBuffer = '\0';    for(int i = 0; i<input.length(); i++){        //first check not space        if(input.charAt(i) != ' '){            char temp = input.charAt(i);            lettercounter++;            if(letterBuffer == temp){                tempcounter++;            }            else{                if(tempcounter%2 == 1){                    oddcounter++;                    if(oddcounter >=2){                        return false;                    }                }                tempcounter = 1;            }            letterBuffer = temp;        }    }    if(lettercounter%2 == 1){        if(oddcounter==1){            return true;        }    }    else{        if(oddcounter == 0){            return true;        }    }    return false;}

(2) Use array to count. Iterate through the string to count the number of each kind of letters into an array with the size of 256(ASCII). Meanwhile, filter the space and count the total number of letters. Based on the total number, use odd judgement or even judgement as discussed above.

private boolean solution2(String input) {    // TODO Auto-generated method stub    //iterate through the string to count the letters    char[] arrayData = new char[baseLength];    int letterCounter = 0;    for(int i = 0; i<input.length(); i++){        if(input.charAt(i) != ' '){            arrayData[input.charAt(i)]++;            letterCounter ++;        }    }    //based on the number of letters to run the different case    if(letterCounter%2 == 1){        return oddcheck(arrayData, 1);    }    else{        return oddcheck(arrayData, 0);    }}private boolean oddcheck(char[] arrayData, int i) {    // TODO Auto-generated method stub    //Iterate through the array to check the number of each kind of letters    int oddcounter = 0;    for(int j = 0 ; j < baseLength ; j++){        if(arrayData[j]%2 == 1){            oddcounter++;            if(oddcounter>i){                return false;            }        }    }    return true;}

(3) “if you think deeply about this problem, you might notice that we don’t actually need to know the counts. We just need to know if the count is even or odd.” This solution results that we only need to use a 26 bits long binary integer to mark each letter’s count. Then based on the letter number to determine the result.
Another tip to check that a number has exactly one 1. Subtract the number with 1, then AND the new number with this number. If there is only one 1 there, the result must be 0.
0000100000 – 1 = 0000011111;
0000100000 % 0000011111 = 00000000000;

/** * This is a smart way. just count the even or odd with filp bits. * @param input * @return */private boolean solution3(String input) {    int bitVector = createBitVector(input);    return bitVector == 0 || checkExactlyOneBitSet(bitVector);}private boolean checkExactlyOneBitSet(int bitVector) {    // TODO Auto-generated method stub    return (bitVector & (bitVector - 1)) == 0;}private int createBitVector(String input) {    // TODO Auto-generated method stub    int bitVector = 0;    for(char c : input.toCharArray()){        int x = getCharNumber(c);        bitVector = toggle(bitVector, x);    }    return bitVector;}private int toggle(int bitVector, int index) {    // TODO Auto-generated method stub    if(index < 0) return bitVector;    int mask = 1<<index;    if((bitVector & mask) == 0){ //find out if there is the same bit in the bitVector        bitVector |= mask; // if no same bit, turns out this is a new bit, add it in    }    else {        bitVector &= ~mask; // if there is the same bit, reset it to 0    }    return bitVector;}/** * Map each character to a number, a->1, b->2, c->3 ... * @param c * @return */private int getCharNumber(Character c){    int a = Character.getNumericValue('a');    int z = Character.getNumericValue('c');    int A = Character.getNumericValue('A');    int Z = Character.getNumericValue('Z');    int val = Character.getNumericValue(c);    if(a <= val && val <= z ){        return val - a;    }    else if(A <= val && val <= Z){        return val - A;    }    return -1;}

What I got:

(1) There is one method to convert the character number out of characters. This turns out to be useful in convert from lower case to higher case or verse versa.
CODE:
(2) The flip though above is useful in the case that only the odd and even matters. The little trick that if there is only one 1, subtract with 1 and use AND, the result must be 0.

1.5 There are three types of edits that can be performed on the string: insert a character, remove a character, or replace a character. Given two strings, Write a function to check if they are one edit (or zero edits) away.

EXAMPLE:pale, ple -> truepales, pale -> truepale, bale -> truepale, bake -> false'

Analysis:

There are three edits. They require 3 different methods.
Insert a character. If this edit happens, the length of first string must be 1 less than the second string. Then there is only one difference between the two. Set a Boolean mark to check the difference occurs. Once the difference was found, the Boolean was set to true. If a second difference was found, just return false.
(1) The length difference is 1 between the two.
(2) There is only one difference between the two.
Remove the character. If this edit happens, the length of first string must be 1 more than the second string. And the rest is the same as above.
(1) The length difference is 1 between the two.
(2) There is only one difference between the two.
Replace a character. If this edit happens. The length must be the same of the two. And there must be only one difference between the two character. The order is the same of the two string.
Reconsider the rules above. The insert and remove edition have the same method. The difference is in insert the second string is longer than the first one. And in remove, the first is longer than the second one.

Solution description:

(1) First check the length of the two. Only allow the string pairs of the length difference is 1 or of the same length pass. Iterate through the strings to check the characters. If and only if there is one difference, return true.

public boolean ChapterOne05(String s1, String s2) {    // TODO Auto-generated constructor stub    int length1 = s1.length();    int length2 = s2.length();    if(length1 == length2){        return replaceCheck(s1, s2);    }    if(length1 - length2 == 1){        return removeCheck(s1, s2);    }    else if(length2 - length1 == 1){        return removeCheck(s2, s1);    }    else{        return false;    }}private boolean removeCheck(String longStr, String shortStr) {    // TODO Auto-generated method stub    boolean different = false;    int i = 0;    for(int j = 0; j < shortStr.length(); j++){        if(longStr.charAt(i) != shortStr.charAt(j)){            if(different == true){                return false;            }            different = true;            j--;        }        i++;    }    return true;}private boolean replaceCheck(String s1, String s2) {    boolean different = false;    for(int i = 0; i<s1.length(); i++){        if(s1.charAt(i) != s2.charAt(i)){            if(different == true){                return false;            }            else{                different = true;            }        }    }    return true;}

(2) The book argue that we can merge the two checking method into one same method. It’s just about moving or not moving the index.

/** * use oen single method to finish the oen check * @param s1 * @param s2 * @return */public boolean ChapterOne05V2(String s1, String s2) {    int length1 = s1.length();    int length2 = s2.length();    if(Math.abs(length1 - length2) >1){        return false;    }    String longer = length1>length2 ? s1 : s2;    String shorter = length1>length2 ? s2 : s1;    int index1 = 0;    int index2 = 0;    boolean isDifferent = false;    while(index1 < shorter.length() && index2 < longer.length()){        if(shorter.charAt(index1) != longer.charAt(index2)){            if(isDifferent == true) return false;            isDifferent = true;            if(length1 == length2){                index1++;            }        }        else{            index1++;        }        index2 ++;    }    return true;}

What I got:

(1) Think one more step in the coding. Whether the codes could be merged together with few additional lines? If so, talk about it.

1.6 Implement a method to perform basic string compression using the counts of repeated characters. For example, the string aabcccccaaa would become a2b1c5a3. If the compressed string would not become smaller than the original string, your method should return the original string. You can assume the string has only uppercase and lower case letters (a - z).

Analysis:

This question is pretty like the question in 1.4. Both the key is counting the letter, but this one requires in order counting.

Solution description:

(1) Use a counter to write down the number of continuous letters. When the letter shifts to a new one, write the counter into the new string and reset to 0. Iterate through the end. At last compare the length.

public String ChapterOne06(String input) {    int counter = 0;    String s = new String();    s += input.charAt(0); //initialize it with the first character    char temp = input.charAt(0);    for(int i = 0; i < input.length(); i++){        if(temp == input.charAt(i)){            counter++;            StringBuilder a = new StringBuilder();        }        else{            s+= counter; //This approach cause a long time waste             //for it requires multiple times of enlarge the String size            counter = 1;            temp = input.charAt(i);            s+= temp;        }    }    s+= counter;    if(s.length() >= input.length())        return input;    return s;}

Use StringBuilder to save operation time.

/** * The book argued that the String is kind of waste time when using multiple times of += * Then it is better to use StringBuilder to replace the String * @param input * @return */public String ChapterOne06V2(String input) {    int counter = 0;    StringBuilder s = new StringBuilder();    s.append(input.charAt(0)); //initialize it with the first character    char temp = input.charAt(0);    for(int i = 0; i < input.length(); i++){        if(temp == input.charAt(i)){            counter++;            StringBuilder a = new StringBuilder();        }        else{            s.append(counter); //This approach cause a long time waste             //for it requires multiple times of enlarge the String size            counter = 1;            temp = input.charAt(i);            s.append(temp);        }    }    s.append(counter);    if(s.length() >= input.length())        return input;    return s.toString();}

(2) The book argues that, the String operation, s += “1”, requires long runtime for every time it runs, the space create a new String to hold the old String and fill in one new character. So, the author suggest to use a StringBuilder() method to avoid the time waste in String reconstruct.

What I got:

(1) When it requires multiple time of String rearrangement, do not just use + operation. Use StringBuilder() instead to gain a higher performance.
(2) Consider the special case. In this question, the special case is when the length of compressed string is not smaller than the source string, drop it. To avoid time waste, firstly check the length of the result appears valuable. This is another optimal solution in special cases.

1.7 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?

Analysis:

First thing that needs to clarify is that the rotation is clockwise or counter-clockwise. Then what the form of this matrix? Is that array of array of the linked list of linked list?
The rest things are simple. Create a new empty matrix to copy old data into new position. Or use old matrix with a buffer to rotate the data to its new position.

public ChapterOne07(int[][] image, int direction, int size) {    // TODO Auto-generated constructor stub    switch (direction){    case 1:        image = clockwise(image,size);        break;    case 2:        image = counterclockwise(image, size);    }    System.out.print(image);}private int[][] counterclockwise(int[][] image, int size) {    // TODO Auto-generated method stub    int temp = 0;    for(int i = 0; i< size/2; i++){        for(int j = i; j<size-i; j++){            temp = image[i][j];            image[i][j] = image[i][size - j];            image[i][size - j] = image[size - i][size - j];            image[size - i][size - j] = image[size - i][j];            image[size - i][j] = temp;        }    }    return image;}private int[][] clockwise(int[][] image, int size) {    // TODO Auto-generated method stub    int temp = 0;    for(int i = 0; i< size/2; i++){        for(int j = i; j<size-i; j++){            temp = image[i][j];            image[i][j] = image[size - i][j];            image[size - i][j] = image[size - i][size - j];            image[size - i][size - j] = image[i][size - j];            image[i][size - j] = temp;;        }    }    return image;}

What I got:

Move data layer by layer, group by group. This results a malfunction method to complete.

1.8 Write a algorithm such that if an element in an MxN matrix is 0, its entire row and column are set to 0.

Analysis:

In this question, there are two steps. First is to find out the positions that hold the value of 0. Then based on the positions, set the row and column.
One thing that’s worth to notice is that, the combination of row and column may be very, but there may be some row and column is the same. Once we figure out what column and what row need to be set to 0, the result is clear to us.
Another situation worth to consider is that if all the rows or all the columns are marked, then we can stop checking and just set the whole matrix to 0.

Solution description:

(1) check the whole matrix to figure out what’s the position of 0. Save the row number and column number into two hash tables. Based on the result, set the matrx.

public ChapterOne08(int[][] matrix, int m, int n) {    // TODO Auto-generated constructor stub    HashSet<Integer> row = new HashSet<Integer>();    HashSet<Integer> column = new HashSet<Integer>();    for(int i = 0; i < m; i++){        for(int j = 0; j<n; j++){            if(matrix[i][j]==0){                row.add(i);                column.add(j);            }        }    }    //set rows    for(int i : row){        for(int k = 0; k < n; k++){            matrix[i][k] = 0;        }    }    //set columns    for(int j : column){        for(int k = 0; k < m; k++){            matrix[k][j] = 0;        }    }    System.out.print(matrix);}

(2) (the less optimal one) check the whole matrix to figure out what’s the position of 0. Save the positions. Check each position and set them to 0.
(3) When set the matrix, instead of set the old matrix to 0, there is another more efficient way when most rows and columns are marked. Create a new matrix and copy the position that is not marked by those rows and columns to form a new one.

/** * this solusion gives another approach to form the desired matrix * @param matrix * @param m * @param n */public void ChapterOne08V2(int[][] matrix, int m, int n) {    // TODO Auto-generated constructor stub    HashSet<Integer> row = new HashSet<Integer>();    HashSet<Integer> column = new HashSet<Integer>();    for(int i = 0; i < m; i++){        row.add(i);    }    for(int i = 0; i < n; i++){        column.add(i);    }    for(int i = 0; i < m; i++){        for(int j = 0; j<n; j++){            if(matrix[i][j]==0){                row.remove(i);                column.remove(j);            }        }    }    int[][] output = new int[m][n];    for(int i : row){        for(int j : column){            output[i][j] = matrix[i][j];        }    }    System.out.print(output);}

(4) In book, there is another efficient way to mark the positions. First check that whether the first row and column has 0 cell. Then check row by row, move the 0s to the first row and column whenever corresponding row or column has a 0 cell. This means taking the first row and column as a buffer to hold the positions. More memory spaces will be saved in this process.

/** * This approach is from the book which use first row and column as a buffer to hold the cell indexes. * The words from book: " * 1. Check if the first row and first column have any zeros,  * and set variables rowHasZero and columnHasZero.(We'll nullify  * the first row and first column later. if necessary.) * 2. Itrate through the rest of the matrix, setting matrix[i][0] and  * matrix[0][j] to zero whenever there's a zero in matrix[i][j]. * 3. Iterate through rest of matrix, nullifying row i if  * there's a  zero in matrix[i][0]. * 4. Iterate through rest of matrix, nullifying column j  * if there's a zero in matrix[0]pj]. * 5. Nullify the first row and first column,  * if necessary(based on values from Step 1). * " *  * @param matrix * @param m * @param n */public void ChapterOne08V3(int[][] matrix, int m, int n) {    boolean rowHasZero = false;    boolean colHasZero = false;    //check if first row has a zero    for(int j = 0; j< n; j++){        if(matrix[0][j] == 0){            rowHasZero = true;            break;        }    }    //check if first column has a zero    for(int i = 0; i < m; i++){        if(matrix[i][0] == 0){            colHasZero = true;            break;        }    }    //check for zeros in the rest of the array    for(int i = 1; i < m ; i++){        for(int j = 1; j < n; j++){            if(matrix[i][j] == 0){                matrix[i][0] = 0;                matrix[0][j] = 0;            }        }    }    //Nullify rows based on values in first column    for(int i = 1; i < m ; i++){        if(matrix[i][0] == 0){            nullifyRow(matrix, i);        }    }    //Nullify column based on values in first column    for(int j = 1; j < n ; j++){        if(matrix[0][j] == 0){            nullifyRow(matrix, j);        }    }    //Nullify first row    if(rowHasZero){        nullifyRow(matrix, 0);    }    //Nullify first column    if(colHasZero){        nullifyColumn(matrix, 0);    }}private void nullifyColumn(int[][] matrix, int i) {    // TODO Auto-generated method stub    for(int j = 0; j < matrix[0].length; j++){        matrix[i][j] = 0;    }}private void nullifyRow(int[][] matrix, int j) {    // TODO Auto-generated method stub    for(int i = 0; i < matrix.length; i++){        matrix[i][j] = 0;    }}

What I got:

(1) My solution gives the approach that rather than do what they ask to do, create a new one and do the rest. When there is not so much non-zero cells left, just copy what left into a new data holder instead of setting all the zero positions to be zero. That a little bit waste memory, but saves time.
(2) What the book discuss is that rather than create a new array, use the original data spaces to save the memory. This is compact but not clear to the reader. More comments is required.

1.9 assume you have a method isSubstring witch checks if one word is a Sub-string 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. ( e.g. “waterbottle” is a rotation of “erbootlewat”).

Analysis:

By observing, the rotation here means that separate one string into two parts and reform them in different order. For example, s1 = arrange. Separate s1 into two as s11 = arr, s12 = ange. Reform them to s12+s11 = angearr. One key thing can be found that if we combine two s2 together and if s2 is rotation of s1, s1 must be a substring of s2+s1.

public boolean ChapterOne09(String s1, String s2) {    // TODO Auto-generated constructor stub    String substr = s2 + s2;    return isSubstring(substr, s1);}

What I got:

Think carefully about the links between the given data. Maybe one duplicate, one add or one subtract will result a brand new perspective.

0 0
原创粉丝点击