Hard Skills of Sword Finger Offer (Programming Questions 1-6)

Posted by abhilashdas on Thu, 30 May 2019 22:05:34 +0200

The full source address of this example is: https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sword

Previous article Soft Skills of Sword Finger Offer I mentioned some soft skills in the interview, how to write my resume and so on. In the later chapters of Offer of Sword Fingers, there are mainly some programming problems with explanations. If you don't have an interview, it's OK to do more of these questions. Unfortunately, the book is implemented in C++, and I implemented it again in Java. If there are errors or better solutions, you are welcome to communicate.

1. Assignment Operator Function

Java does not support assignment operator overloading.

2. Implementing Singleton Mode

The Hungry Man Model

 1 /**
 2 * Starving model
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public class Singleton {
 7 
 8    private static Singleton singleton = new Singleton();
 9 
10    private Singleton() {
11 
12    }
13    public static Singleton getInstance() {
14        return singleton;
15    }
16 }

Advantages: Thread safety, error-prone, high performance.

Disadvantage: A singleton is instantiated at the time of class initialization, which takes up memory.

Model 1

 1 /**
 2 * Full-Han Model I
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public class Singleton {
 7 
 8    private static Singleton singleton ;
 9 
10    private Singleton() {
11 
12    }
13    public static synchronized Singleton getInstance() {
14        if (singleton == null) {
15            singleton = new Singleton();
16        }
17        return singleton;
18    }
19 }

Full Men Model II

 1 /**
 2 * Full-Han Model II
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public class Singleton {
 7 
 8    private static Singleton singleton ;
 9 
10    private Singleton() {
11 
12    }
13    public static Singleton getInstance() {
14        if (singleton == null) {
15            synchronized (Singleton.class) {
16               if (singleton == null) {
17                  singleton = new Singleton();
18               }
19            }
20        }
21        return singleton;
22    }
23 }

Advantages: Threads are safe, memory is saved, and objects are instantiated when needed, which is better than locking methods.

Disadvantage: Due to lock, performance is still not as good as Hunger mode.

Enumeration mode

 1 /**
 2 * Typesafe Enum pattern
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public enum Singleton {
 7    INSTANCE;
 8 
 9    Singleton() {
10 
11    }
12 }

In Effective Java, the author strongly recommends enumerating to achieve singletons. In addition, the enumeration guarantees thread safety from the bottom, which interested readers can understand in depth. Although enumeration implementations of singletons may seem "alternative", in many ways, this is the best and safest way.

3. Repeated numbers in arrays

Title: Given an array, find the duplicate numbers in the array.

Solution 1: Time complexity O(n), Space complexity O(n)

 1 /**
 2 * Find duplicate numbers in an array
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public class Solution {
 7 
 8    public void findRepeat(Integer[] array) {
 9        Set<Integer> noRepeat = new HashSet<>();
10        for (Integer number : array) {
11            if (!noRepeat.contains(number)) {
12                noRepeat.add(number);
13            } else {
14                System.out.println("Repeat numbers:" + number);
15            }
16        }
17    }
18 }

* Set's underlying implementation is also a Map

Through the Map hash structure, duplicate numbers in the array can be found. The algorithm has O(n) time complexity and O(n) space complexity (an additional Map needs to be defined).

Solution 2: Time complexity O(n^2), Space complexity O(1)

 1 /**
 2 * Find duplicate numbers in an array
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public class Solution {
 7 
 8    public void findRepeat(Integer[] array) {
 9        for (int i = 0; i < array.length; i++) {
10            Integer num = array[i];
11            for (int j = i + 1; j < array.length; j++) {
12                if (num.equals(array[j])) {
13                    System.out.println("Repeat numbers:" + array[j]);
14                }
15            }
16        }
17    }
18 }

Solution 2 finds repetitive array elements by traversing. Compared with solution 1, solution 2 is a typical "space for time" algorithm.

Deformation: Given an array with a length of n, the size of the number in the array ranges from 0 to n-1. Find out the duplicate numbers in the array.

The deformed problem can also be solved by the above two methods. The numerical value ranges from 0 to n-1. The algorithm traverses once (time complexity O(n)) without extra space (space complexity O(1)).

 1 /**
 2 * Find out the duplicate numbers in the array. The values of the numbers in the array range from 0 to n-1.
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public class Solution {
 7    public void findRepeat(Integer[] array) {
 8        for (int i = 0; i < array.length; i++) {
 9            while (array[i] != i) {
10                if (array[i].equals(array[array[i]])) {
11                    System.out.println("Repeat numbers:" + array[i]);
12                    break;
13                }
14                Integer temp = array[i];
15                array[i] = array[temp];
16                array[temp] = temp;
17            }
18        }
19    }
20 }

Analysis: Conditions appear in the deformed topic, and the range of values in the array is within the len gt h of the array n-1, and the minimum is 0. That is to say, any value in an array does not cross the bounds as an array subscript, which is a potential condition. According to this potential condition, we can place each value in the corresponding array subscript, so that the array subscript = the array value. For example: 4,2,1,4,3,3. Traverse through the first value 4, when the subscript is 0, array subscript array value, compare array[0] and array[4] is not equal - > exchange, 4 put in the correct position, get 3, 2, 1, 4, 4, 3. At this time, the first value is 3, the array subscript is still the array value, comparing array[0] and array[3] do not want to wait - > exchange, 3 put in the correct position, get 4, 2, 1, 3, 4, 3. At this point, the array subscript is still the array value, comparing array[0] and array[4] is equal, and exits the current loop. By analogy, start the loop with the array subscript int=1.

4. Finding in two-dimensional arrays

Topic: Given a two-dimensional array, each row is sorted in order of increasing from left to right, and each column is sorted in order of increasing from top to bottom. Enter a two-dimensional array and an integer to determine whether the integer is in a two-dimensional array.

Solution 1: Traversing two-dimensional arrays of n*m size, time complexity O(n*m), space complexity O(1)

 1 /**
 2 * Finding in Two-Dimensional Array
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public class Solution {
 7 
 8    public boolean isExist(Integer[][] twoArray, Integer target) {
 9        for (int i = 0; i < twoArray.length; i++) {
10            for (int j = 0; j < twoArray[i].length; j++) {
11                if (twoArray[i][j].equals(target)) {
12                    return true;
13                }
14            }
15        }
16        return false;
17    }
18 }

Advantages: Simple violence.

Disadvantage: The performance is not optimal, the time complexity is high, and the "orderly" condition of the topic is not fully utilized.

Solution 2: Time complexity O(n+m), Space complexity O(1)

 1 /**
 2 * Finding in Two-Dimensional Array
 3 * @author OKevin
 4 * @date 2019/5/27
 5 **/
 6 public class Solution {
 7 
 8    public boolean isExist(Integer[][] twoArray, Integer target) {
 9        int x = 0;
10        int y = twoArray[0].length - 1;
11        for (int i = 0; i < twoArray.length-1 + twoArray[0].length-1; i++) {
12            if (twoArray[x][y].equals(target)) {
13                return true;
14            }
15            if (twoArray[x][y] > target) {
16                y--;
17                continue;
18            }
19            if (twoArray[x][y] < target) {
20                x++;
21            }
22        }
23        return false;
24    }
25 }

Analysis: By giving an example, we can find out the rules and start from the upper right corner.

  Integer[][] twoArray = new Integer[4][4];

  twoArray[0] = new Integer[]{1, 2, 8, 9};

  twoArray[1] = new Integer[]{2, 4, 9, 12};

  twoArray[2] = new Integer[]{4, 7, 10, 13};

  twoArray[3] = new Integer[]{6, 8, 11, 15};

5. Replace the blanks

Title: Replace the space in the string with "20%".

Solution 1: Direct substitution according to the replaceAll method provided by Java

 1 /**
 2 * String space replacement
 3 * @author OKevin
 4 * @date 2019/5/28
 5 **/
 6 public class Solution {
 7    public String replaceSpace(String str) {
 8        return str.replaceAll(" ", "20%");
 9    }
10 }

There is nothing to say about this solution. But you can learn about replaceAll's JDK implementation. ReplceAll is implemented in JDK by matching strings to be replaced based on regular expressions.

Solution 2: Replacement by changing space for time

 1 /**
 2 * String space replacement
 3 * @author OKevin
 4 * @date 2019/5/28
 5 **/
 6 public class Solution {
 7    public String replaceSpace(String str, String target) {
 8        StringBuilder sb = new StringBuilder();
 9        for (char c : str.toCharArray()) {
10            if (c == ' ') {
11                sb.append(target);
12                continue;
13            }
14            sb.append(c);
15        }
16        return sb.toString();
17    }
18 }

6. Print the linked list from end to end

Title: Enter the head node of a linked list and print the value of each node from end to end.

* Because Sword Finger Offer uses C++ programming language, this problem requires us to construct a node to simulate the structure of the linked list.

Define nodes

 1 /**
 2 * Link List Node Definition
 3 * @author OKevin
 4 * @date 2019/5/29
 5 **/
 6 public class Node {
 7    /**
 8     * Point to the next node
 9     */
10    private Node next;
11    /**
12     * Represents the range of nodes
13     */
14    private Integer data;
15 
16    public Node(){}
17 
18    public Node(Integer data) {
19        this.data = data;
20    }
21    //ellipsis getter/setter Method
22 }

Solution 1: Make use of the characteristics of the first-in-last-out stack, traverse the list and put it in the stack, and then push the data out of the stack.

 1 /**
 2 * Reverse printing of linked list values
 3 * @author OKevin
 4 * @date 2019/5/29
 5 **/
 6 public class Solution {
 7    public void tailPrint(Node head) {
 8        Stack<Node> stack = new Stack<>();
 9        while (head != null) {
10            stack.push(head);
11            head = head.getNext();
12        }
13        while (!stack.empty()) {
14            System.out.println(stack.pop().getData());
15        }
16    }
17 }

This solution "unfortunately" relies on extra space.

Solution 2: Since the stack structure is used, in fact, the linked list can be printed backwards in a recursive way.

 1 /**
 2 * Reverse printing of linked list values
 3 * @author OKevin
 4 * @date 2019/5/29
 5 **/
 6 public class Solution {
 7    public void tailPrint(Node head) {
 8        if (head.getNext() != null) {
 9            tailPrint(head.getNext());
10        }
11        System.out.println(head.getData());
12    }
13 }

Recursion avoids additional memory space, but if the list is too long and the recursion is too deep, it can easily lead to call stack overflow.

Testing procedures:

 1 /**
 2 * @author OKevin
 3 * @date 2019/5/29
 4 **/
 5 public class Main {
 6    /**
 7     * 1->2->3->4->5
 8     * @param args
 9     */
10    public static void main(String[] args) {
11        Node node1 = new Node(1);
12        Node node2 = new Node(2);
13        Node node3 = new Node(3);
14        Node node4 = new Node(4);
15        Node node5 = new Node(5);
16        node1.setNext(node2);
17        node2.setNext(node3);
18        node3.setNext(node4);
19        node4.setNext(node5);
20 
21        Node head = node1;
22 
23        Solution solution = new Solution();
24        solution.tailPrint(head);
25    }
26 }

The full source address of this example: https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sword

Continuous updates, please pay attention to the public number

 

 

This is a public number that adds buff to programmers.

Topics: PHP Java github Programming JDK