Interview question 3 of the second edition of sword finger offer: repeated numbers in the array (java)

Interview question 3: repeated numbers in the array

Title 1: all numbers in an array of length n are in the range of 0 to n-1. Some numbers in the array are repeated, but I don't know how many numbers are repeated, nor how many times each number is repeated. Please find any duplicate number in the array. For example, if you input an array of length 7 {2, 3, 1, 0, 2, 5, 3}, the corresponding output is the repeated number 2 or 3.

  • Method 1: because all numbers are 0-n-1, you can know which number is repeated by sorting the array and traversing it. The array sorting time complexity is O(nlogn).

  • Method 2: traverse the array and store it in the hash table. When traversing the element, judge that if the element already exists in the hash table, the element repeats. If the element does not exist, add the element to the collection. Because the judgment of the hash table is O(1), the time complexity is O(n) (traversing the array), but the cost of improving the time is an O(n) hash table.

  • Method 3: because the range is from 0 to n-1, if the corresponding footmark is placed at each position, if the element on the footmark is the same as the element to be placed, there are duplicate numbers. Because each element can reach its due position by exchanging at most twice, the time complexity is O(n) and the space complexity is O(1) (because no additional space is required).

    Implementation of method 3: (it is roughly the same as that in the book, but it lacks judgment on the input content. The answer is a for loop, in which the exchange uses a while loop)

    package com.ldl.forbuilding.controller;
    
    public class HugerSingletonTest {
        public static void main(String[] args) {
            int[] arr = {2,3,1,0,2,5,3};
            System.out.println(findnumber(arr));;
        }
        public static int findnumber(int[] arr){
            int i = 0;
            while (i<arr.length){
                if (arr[i]!=i){
                    if(arr[arr[i]]==arr[i]){
                        return arr[i];
                    }
                    int temp = arr[arr[i]];
                    arr[arr[i]] = arr[i];
                    arr[i] = temp;
                }else {
                    i++;
                }
            }
            return 0;
        }
    }
    

    answer:

    public class Solution {
        public static boolean duplicate(int[] arr) {
            // Incoming inspection
            if (arr == null || arr.length == 0) {
                return false;
            }
            for (int i = 0; i < arr.length; i++) {
                if (arr[i] < 0 || arr[i] >= arr.length) {
                    return false;
                }
            }
    
            // Traversal array
            for (int i = 0; i < arr.length; i++) {
                while (arr[i] != i) {
                    if (arr[i] == arr[arr[i]]) {
                        System.out.println(arr[i]);
                        return true;
                    }
                    // replace
                    int temp = arr[i];
                    arr[i] = arr[temp];
                    arr[temp] = temp;
                }
            }
            return false;
        }
    
        public static void main(String[] args) {
            int[] arr = {1, 1, 2, 4, 2, 5, 6};
            boolean result = duplicate(arr);
            System.out.println(result);
        }
    }
    

Topic 2: in an array with length n+1, all numbers are in the range of 1~n, so at least one number in the array is repeated. Please find any duplicate number in the array, but the input array cannot be modified. For example, if you enter an array {2,3,5,4,3,2,6,7} with a length of 8, the corresponding output is the repeated number 2 or 3.

  • Method 1: create a new array of n+1 size and traverse the input array. If the element size corresponds to an empty element at the new array footer, put the element into the new array, and so on. When the element on the new array footer corresponding to the traversed element is not empty, it indicates that there are duplicate elements. Time O(n), space O(n).

    • Handwritten

      package com.ldl.forbuilding.controller;
      
      public class HugerSingletonTest {
          public static void main(String[] args) {
              int[] arr ={2,3,5,4,3,2,6,7};
              System.out.println(findnumber(arr));;
          }
          public static boolean findnumber(int[] arr){
              int[] temp = new int[arr.length];
              for (int i = 0; i < arr.length; i++) {
                  if(arr[i]==temp[arr[i]]){
                      System.out.println(arr[i]);
                      return true;
                  }else {
                      temp[arr[i]]=arr[i];
                  }
              }
              return false;
          }
      }
      
    • answer

      public class Solution {
          public static int getDuplication(int[] arr) {
              // Incoming inspection
              if (arr == null || arr.length == 0) {
                  return -1;
              }
              for (int i = 0; i < arr.length; i++) {
                  if (arr[i] < 1 || arr[i] >= arr.length) {
                      return -1;
                  }
              }
      
              int[] tempArr = new int[arr.length];
              for (int i = 0; i < arr.length; i++) {
                  if (arr[i] == tempArr[arr[i]]) {
                      return arr[i];
                  }
                  tempArr[arr[i]] = arr[i];
              }
              return -1;
          }
          public static void main(String[] args) {
              int[] numbers = {2, 1, 5, 4, 3, 2, 6, 7};
              System.out.println(getDuplication(numbers));
          }
      }
      

    If the interviewer requires a spatial complexity of O(1), we will use method 2.

  • Method 2: judge the occurrence times of elements in 1m by binary search (half search). If it is less than m times, repeat the elements in m+1n. Split m+1~n in half to judge the occurrence times of elements. For example: for an array with length of 8, the element range is 17. Then, the number of occurrences of 14 is 5 (judge whether each element is greater than or equal to 1 and less than or equal to 4 by directly traversing the array), which is greater than 4. Therefore, there must be duplicate elements in 14. Split again. 12 occurs twice (note that 2 is also a duplicate element at this time, but this method can't judge!), and 34 occurs three times. Therefore, there must be repeated elements in 34. Split again. 3 occurs twice and 4 occurs once. Find the duplicate element 3.

    • Handwritten (look at the answers written out... I forgot to find the two points)

      package com.ldl.forbuilding.controller;
      
      public class HugerSingletonTest {
          public static void main(String[] args) {
              int[] arr ={2,3,5,4,3,2,6,7};
              System.out.println(findnumber(arr));;
          }
          public static int findnumber(int[] arr){
              // Incoming inspection
              if (arr == null || arr.length == 0) {
                  return -1;
              }
              for (int i = 0; i < arr.length; i++) {
                  if (arr[i] < 1 || arr[i] >= arr.length) {
                      return -1;
                  }
              }
              int left = 1;
              int right = arr.length-1;
              while (left<=right){
                  int mid = (right-left)/2+left;
                  int count = findcount(arr,left,mid);
                  if(left==right){
                      if(count>1){
                          return left;
                      }else {
                          break;
                      }
                  }
                  if(count>mid-left+1){
                      right=mid;
                  }else {
                      left=mid+1;
                  }
              }
              return -1;
          }
          public static int findcount(int[] arr,int left,int right){
              int count =0 ;
              for (int i = 0; i <arr.length ; i++) {
                  if(arr[i]>=left&&arr[i]<=right){
                      ++count;
                  }
              }
              return count;
          }
      }
      

      Binary search O(logn), traverse the array O(n) with length N, so input the array with length N, then the findcount function will be called O(logn) times, each time is O(n), so the total time complexity is O(nlogn), and the space complexity is O(1). Compared with the previous time and space are O(n), time changes space.

Posted by akshay on Sun, 28 Nov 2021 08:46:27 -0800