Swordfinger offer 5 - Search Algorithm

Posted by gmccague on Tue, 08 Feb 2022 21:56:25 +0100

Number of occurrences of number 53 in ascending array

Given a non-descending array of length n and a non-negative integer k, it is required to count the number of times K occurs in the array
Requirements: Spatial Complexity O(1), Time Complexity O(logn)

Ideas: dichotomy.

1.mid=array.length/2; Divided into [0,mid] [mid+1;length-1]
If (array[mid]<k) is two to [mid+1;length-1], otherwise it is two to [0,mid].

2.Set-1 to indicate that you can't find it, and then go back to 0

3. When mid is found, look at the previous and subsequent digits that are not within the range of subscripts and are not equal to k. If they continue pushing equally, they will not return to mid directly
Recursive Writing, while works*/

public class Solution {
    public int GetNumberOfK(int [] array , int k) {
        if(array == null || array.length == 0)  return 0;
        int first=GetFirst( 0, array.length-1, k,array);
        int last=GetLast( 0, array.length-1, k,array);
         if(first > -1 && last > -1) return last - first + 1;//Find it, just make a difference+1
         return 0;//If both left and right are -1, K is not found and should be returned directly to 0
    }
    
    int GetFirst(int start,int end,int k,int[] arr){
        if(start>end) return -1;
        int mid=start+(end-start)/2;
        if(arr[mid]>k) return GetFirst(start,mid-1,k,arr);
        if(arr[mid]<k) return GetFirst(mid+1,arr.length-1,k,arr);
        else{ //The biggest puzzle is how to find the k... ahead. Continue recursion if the previous number equals = k
            if(mid-1>=0&&arr[mid-1]==k) return GetFirst(start,mid-1,k,arr);
            else return mid;}
                                                   }
     int GetLast(int start,int end,int k,int[] arr){
         while(start<=end){
             int mid=start+(end-start)/2;
              if(arr[mid]>k)    end=mid-1;
             else if(arr[mid]<k)   start=mid+1;
             else{
                 if(mid+1<=end&&arr[mid+1]==k) start=mid+1;
                 else return mid; }
             mid=(start+end)<<2; }
          return -1;
      }
}

4. Finding in a two-dimensional array

In a two-dimensional array array with the same length of each one-dimensional array, each row is sorted in increasing order from left to right, and each column is sorted in increasing order from top to bottom. Please complete a function, enter such a two-dimensional array and an integer to determine if the array contains the integer.

[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]

Given target = 7, returns true.

Given target = 3, returns false.
Advanced: Spatial Complexity O(1)O(1), Time Complexity O(n+m)

Ideas: From the lower left corner, if greater than right, less than top, equal to return (rows and columns must be in range)

public class Solution {
    public boolean Find(int target, int [][] array) {
         int row=array.length-1;
         int low=0;
        while(row>=0&&low<=array[0].length-1){
            if(array[row][low]>target) row--;
            else  if(array[row][low]<target) low++;
            else return true;
        }
        return false;
    }
}

11. Rotate the minimum number of arrays

There is a non-descending array of length n, such as [1,2,3,4,5], that rotates it by moving the first few elements of an array to the end of the array and turning it into a rotated array, such as [3,4,5,1,2], or [4,5,1,2,3]. Given such a rotated array, find the minimum value in the array.

Requirements: Spatial Complexity: O(1), Time Complexity: O(logn)

The idea is: non-descending array, then based on the intermediate value, arr[mid]>arr[end] then the minimum value should be after mid;

Otherwise, high==mid (i.e., the middle value <right, then the middle value is the right boundary, because the middle value is the dividing line, both sides are increasing, the right increment package does not include the middle element 2; when the middle value==the right boundary is appropriate, the right boundary moves forward to continue judging (always moving to the minimum value there)

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array.length<=0) return 0;
        int low=0; int high=array.length-1;
       
        while(low<high){
            int mid=low+(high-low)/2;
            if(array[mid]>array[high]) low=mid+1;
            else if(array[mid]<array[high]) high=mid;
            else high--;
        }
        return array[low];
    }
}

44. A digit in a sequence of numbers

The number is 0123456789101112131415... As a character sequence, the second digit in the sequence (calculated from subscript 0) is 2, the tenth digit is 1, and the 13th digit is 1. For this kind of question, please output the corresponding number in the nth digit.

Ideas: [1,9] 1x9=9; [10,99] 2x90=180; [100,999] 3x900=2700

1. Find in which interval n-9-180-2700 until it is less than 0

int base=1; int count=1; (digits)

while(n-base*9*count>0){

n-=9*base*count;base=base*10;count++;

}//base at the end of the loop is the starting value of our interval, and n at that time is also.... '

2. If there is no remainder for n, it is the previous number//191-189=2--100,193-189=4--101

int len=n%count; int num=base+(n-1)/count;

import java.util.*;
public class Solution {
    public int findNthDigit (int n) {
       int count=1;//Number of digits per interval
        int base=1;
        while(n-9*base*count>0){ //190
            n-=9*base*count;//181-180=1
            base=base*10;
            count++; }
        //while loops out that n has reached the interval in which the value is located, as well as the number of digits,
        //base interval start
         int curNum=(n-1)/count+base;//Required num
        int resDigit = 0;
        for (int i=n%count; i<count; i++){
             resDigit = curNum % 10;
            curNum /= 10;
        }
          return resDigit;
    }
}

Topics: Algorithm linq p2p