"Prove safety offer" an array of topics (cow-off 10.22)

Test sites: traverse, search, sort, time and space efficiency, thinking, sorting algorithms

// Q01 partially ordered two-dimensional array [Find] make good use of nature

(The length of each one-dimensional array of same), each row from left to right in order of ascending sort, to sort each column in a two-dimensional array in order of increasing from top to bottom. A complete function, enter such a two-dimensional array and an integer, it is determined whether the array contains the integer.

Since the matrix partially ordered, up diminishing numbers, the right digital increment:

  1. Target figures will only appear at the beginning less than the number of rows
  2. Traversing row i, column j if the corresponding element is greater than the target, then the previous row i-1, j-th column in the target and only appear later.

Therefore, from the lower left corner to start looking. Than the lower left corner of the target digital hours, the shift; to be the target when the number is larger than the lower left corner, the right.
Route search is stepped, the complexity is O (+ number of columns the number of rows).

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        int nrows = array.size();
        int ncols = array[0].size();
         
        int i = nrows - 1, j = 0;
         
        while(i >= 0 && j < ncols){
            if(array[i][j] == target) return true;
            else if(array[i][j]< target ){
                j++;
            }else i--;
        }
         
        return false;
    }
};

WA Warning:

Error code follows the previous version, since the determination conditions && written, causing mistakes (bounds array access):

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        int nrows = array.size();
        int ncols = array[0].size();
        if( ncols == 0 || nrows == 0) return false;
        for(int i = nrows - 1, j = 0; i >= 0, j < ncols; i--){
            if( array[i][j] == target )
                return true;
            if( array[i][j] < target){
                i++;
                j++;
            }
        }
          
        return false;
    }
};

// Q06 rotating the smallest element in the array half [of violence] ||

The beginning of an array of several elements moved to the end of the array, the array we call rotation.
A non-descending order of the input array of a rotation of the output rotary smallest element array.
For example, an array {3,4,5,1,2} {1,2,3,4,5} is a rotation of the array to a minimum.
NOTE: All the elements are given in greater than 0, if the array size is 0, return 0.

Due to the rotation, the front half of the array of non-reducing, non-reducing half section, the forward traverse from the turning point must be the smallest element. If there is no turning point, then all the elements are equal.
. ·
. · ``

But the turning point can try half. Since the right side of the turning point is the smallest element, so they chose to try to make the right end of the interval point falls on the smallest element. Then:

  1. array[mid] > array[high]
    This situation is similar to array [3,4,5,6,0,1,2], in this case a certain minimum number of mid right.
    low = mid + 1
  2. array[mid] == array[high]:
    This situation is similar to the array [1,0,1,1,1] or [1,1,1,0,1], determined in this case the minimum number of bad mid left or right, then had a step narrow range.
    high = high - 1
  3. array[mid] < array[high]:
    This situation is similar to the array [2,2,3,4,5,6,6], then the minimum number of array necessarily [mid] to the left or the mid. Because the right is inevitably increasing.
    high = mid

Note that, considering the last segment length is 2 or 3 for the case where the above-described embodiment are that the convergence final low and high point to the smallest element.

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size()==0)
            return 0;
        int lo =0, hi = rotateArray.size()-1,mid;
         
        while(lo< hi){
            mid = lo+((hi-lo)>>1);
            if(rotateArray[mid]>rotateArray[hi])
                lo=mid+1;
            else if (rotateArray[mid] == rotateArray[hi])
                hi-=1;
            else hi=mid;
        }
        return rotateArray[hi];
    }
};

Q13 adjusting the even order of the array before the ODD

Enter an array of integers, to realize a function to adjust the order of the numbers in the array, such that all the odd part of the front half of the array, is located in the second half of all the even array, and between odd and ensure a relatively even, odd and even the same position.

Method 1: open a new array, first add odd, then add the even. The code slightly.

Method 2: without the aid of additional memory

/**
 * 1.要想保证原有次序,则只能顺次移动或相邻交换。
 * 2.i从左向右遍历,找到第一个偶数。
 * 3.j从i+1开始向后找,直到找到第一个奇数。
 * 4.将[i,...,j-1]的元素整体后移一位,最后将找到的奇数放入i位置,然后i++。
 * 5.終止條件:j向後遍歷查找失敗。
 */
public void reOrderArray2(int [] a) {
    if(a==null||a.length==0)
        return;
    int i = 0,j;
    while(i<a.length){
        while(i<a.length&&!isEven(a[i]))
            i++;
        j = i+1;
        while(j<a.length&&isEven(a[j]))
            j++;
        if(j<a.length){
            int tmp = a[j];
            for (int j2 = j-1; j2 >=i; j2--) {
                a[j2+1] = a[j2];
            }
            a[i++] = tmp;
        }else{// 查找失敗
            break;
        }
    }
}
boolean isEven(int n){
    if(n%2==0)
        return true;
    return false;
}

/ Q19 clockwise print variable matrix [use] the border

Enter a matrix, in order from outside to inside in a clockwise order to print out sequentially for each number, for example, if you enter the following 4 X 4 matrix: 1 2. 6. 7. 8. 3. 4. 9 10. 5. 11
12 is 14 15 16 13 is sequentially printed out digital 1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

/**
 A--------------------------------------------------------
 * 思路1:vis数组记录 - 简单但浪费空间
 * 思路2:用变量记录当前是第几圈 - 边界计算有点麻烦
 * 思路☆:用四个变量分别记录当前的四周边界,检查是否在边界内 && 边界是否满足条件
 T--------------------------------------------------------
 * 注意边界的检查(保证[在边界内 && 边界合法]) 
 */

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> ans = new ArrayList<>();

        if(matrix.length == 0 || matrix[0].length == 0)
            return ans;

        int nrow = matrix.length, ncol = matrix[0].length;
        int top=0,left=0,bottom=nrow-1,right=ncol-1;
        while (top<=bottom&&left<=right){
            // top: left -> right
            for(int i=left;i<=right;i++){
                ans.add(matrix[top][i]);
            }top++;
            // right: top -> bottom
            for(int i=top;i<=bottom&&left<=right;i++){//其实这里left<=right的判断多余,因为left和right的值都还没有变化
                ans.add(matrix[i][right]);
            }right--;
            // bottom: right -> left
            for(int i=right;i>=left&&top<=bottom;i--){
                ans.add(matrix[bottom][i]);
            }bottom--;
            // left: bottom -> top
            for(int i=bottom;i>=top&& left<=right;i--){
                ans.add(matrix[i][left]);
            }left++;
        }
        return ans;
    }
}

/ Q28 occurs more than half of the numbers to find out the array

There are a number of array number that appears more than half the length of the array, find this number. For example, a length of the input array 9 {1,2,3,2,2,2,5,4,2}. Since the number 2 appears five times, more than half the length of the array in the array, the output 2. If there is 0 output.

Method 1: HashMap count the number of times each number appears

/**
 * 用 HashMap 统计各个数字出现的次数
 * 注意 HashMap 的使用方法
 */

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Solution {
    public int  MoreThanHalfNum_Solution(int [] array) {
        HashMap<Integer,Integer> map = new HashMap<>();

        for(int i=0;i<array.length;i++){
            if(!map.containsKey(array[i])){
                map.put(array[i],1);
            }else{
                int cnt = map.get(array[i]);
                map.put(array[i],++cnt);
            }
        }

        Iterator iter = map.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry entry = (Map.Entry)iter.next();
            Integer key = (Integer)entry.getKey();
            Integer val = (Integer)entry.getValue();
            if(val>array.length/2){
                return key;
            }
        }
        return 0;
    }
}

Method 2: Partition lookup based on a large K O (n)

For the array, if there is more than half of the number of occurrences, then after a certain array in the middle of the digital sorted array (median), then utilize O (n) lookup (= n / 2) Algorithm for large K .

/**
 * 由于每次 partition 后,pivot 左边的值都较小,右边的值都较大,
 * 所以当 pivot 位置为 K 时,pivot 的值为第 K 大的值。
 * 不断对区间进行划分使得 pivot 位于 K, 然后检验它出现的次数是否大于一半。
 */

public class Solution {
    public int  MoreThanHalfNum_Solution(int [] array) {
        if(array == null||array.length ==0)
            return 0;
        int mid = array.length/2;
        int start = 0, end = array.length-1;
        int index = Partition(array,start,end); // 左闭右闭
        while(index!=mid){
            if(index > mid){
                index = Partition(array,start,index-1);
            }else{
                index = Partition(array,index+1,end);
            }
        }
        int result = array[index];

        if(check(array,result,mid))
            return result;

        return 0;
    }

    private int Partition(int[] arr, int start, int end) {
        int pivot = arr[start];
        int left = start, right = end;
        while (left < right) {
            // 因为pivot取的是最左边,所以要先从右边找
            while (left < right && arr[right] >= pivot) right--;
            arr[left] = arr[right];
            while (left < right && arr[left] <= pivot) left++;
            arr[right] = arr[left];
        }
        arr[left] = pivot;
        return left;// left 为最后枢值所在的位置
    }

    private boolean check(int[] arr, int result, int mid){
        int times=0;

        for (int anArr : arr) {
            if (anArr == result)
                times++;
        }
        if(times*2>arr.length)
            return true;
        return false;
    }
}

Method 3: Analyzing traversing pairwise cancellation

If you have qualified a number, and the number of times it appears even more than all the other times the number that appears.
The essence of the idea is that a pair of different numbers destructive, then the qualifying numbers must be left to the last digit.
Save when traversing an array of two values: one is a numeric array, one number. When traversing the next number, if it is previously stored in the same figure, plus the number 1 or decremented by 1; if the number is 0, the next number is saved, and the number is set to 1. After traversing the saved numbers is also desired. And then determine whether it meets the conditions can be.

/ Max and [dp, Math.max ()] continuous subarray Q30

HZ occasionally get some professional issues to flicker those non-computer science students. After the test group will finish today, he spoke up: in the old one-dimensional pattern recognition, it is often necessary to calculate the maximum and continuous sub-vector when the vector is a positive whole number, the problem solved. However, if the vector contains a negative number, it should contain a negative number, and expect a positive number next to it would make up for it? For example: {6, -3, -2,7, -15,1,2,2}, and the maximum successive sub-vectors of 8 (beginning from 0, up to the third). To an array and returns its maximum continuous subsequence and you will not be fooled him live? (Sub-vector length is at least 1)

/**
 * dp[i] 为以 array[i] 为末尾的最大子向量和
 * dp[i] = max(dp[i-1]+a[i], a[i])
 */

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        if(array==null||array.length==0)
            return 0;

        int rst = array[0],dp = array[0];

        for(int i=1;i<array.length;i++){
            dp = Math.max(dp+array[i],array[i]);
            rst=Math.max(rst,dp);
        }

        return rst;
    }
}

/ Q32 arranged in the minimum number of array [Collections.sort (), Integer.toString (int n), stringBuilder.append (str)]

Enter a positive integer array, the array of all the numbers arranged in a number spliced ​​together, the splice can print out all numbers smallest one. 3,32,321 input array} {e.g., print the minimum number of three numbers can be arranged to 321,323.

/**
 * 不是比较字典序!
 *
 * 先将整型数组转换成String数组,然后排序,最后将排好序的字符串数组拼接。
 * 关键就是制定排序规则:
 * 若ab > ba 则 a > b,
 * 若ab < ba 则 a < b,
 * 若ab = ba 则 a = b;
 * 解释说明:
 * 比如 "3" < "31"但是 "331" > "313",所以要将二者拼接起来进行比较
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        if(numbers==null||numbers.length==0)
            return "";
        ArrayList<String> arrayList = new ArrayList<>();
        for(int n:numbers)
            arrayList.add(Integer.toString(n));

        // 重定义 Collections.sort()的排序规则
        Collections.sort(arrayList, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                String s1=o1+o2;
                String s2=o2+o1;
                return s1.compareTo(s2); // 返回的值小于0则表示 s1<s2, s1 排在 s2 前
            }
        });


        StringBuilder rst=new StringBuilder();
        for(String s:arrayList){
            rst.append(s);
        }

        return rst.toString();
    }
}

Concise written as, temporarily not understand.

public String PrintMinNumber(int [] numbers) {
        ArrayList<Integer> list = new ArrayList();
        Arrays.stream(numbers).forEach(list::add);
 
        list.sort((str1, str2) -> {
            String s1 = str1 + "" + str2;
            String s2 = str2 + "" + str1;
            return s1.compareTo(s2);
        });
 
        String s = "";
        for (int j : list) {
            s += j;
        }
 
        return s;
    }

Array.sort() to_string(int n)

/// Q35 array of reverse

Two numbers in the array, if a number is greater than the front behind the figures, the two numbers form a reverse pair. Enter an array, this array P. finds the total number of reverse pair P and outputs the result modulo 1000000007. I.e., the output P% 1000000007

Input:

Title ensure the same digital data of the range of the input array is not: For data% 50, size <= 10 ^ 4 for data% 75, size <= 10 ^ 5 for data% 100, size <= 2 * 10 ^ 5

Example:

Reverse logarithmic 1,2,3,4,5,6,7,0 is 7.

Method 1: Merge sort of reverse Statistics

Recursive merge sort process, a first section divided into two sections obtained about two ordered, then the left and right sections merge.

While about orderly interval can be calculated in reverse order in the section number, the number can be reverse between the merging section. Interval = inverse number of the number of reverse rooms reverse order and two subintervals + subinterval.

Required by O (n) auxiliary space merge.

public class Solution {
    public int InversePairs(int[] array) {
        if (array == null || array.length == 0)
            return 0;
        int[] arr = array.clone();
        int[] copy = arr.clone();
        int MOD = 1000000007;
        long ans = MergeSort(arr, copy, 0, arr.length, MOD);// [ , )
        return (int) (ans % MOD);
    }

    private long MergeSort(int[] arr, int[] copy, int start, int end, int MOD) {// [ , )
        long count = 0;
        if (start + 1 < end) {
            int mid = (start + end) / 2;
            long a = MergeSort(arr, copy, start, mid, MOD);
            long b = MergeSort(arr, copy, mid, end, MOD);
            long c = Merge(arr, copy, start, mid, end, MOD);
            count = a + b + c;
        }
        return count % MOD;
    }

    private long Merge(int[] arr, int[] copy, int start, int mid, int end, int MOD) {
        long count = 0;
        
        System.arraycopy(arr, start, copy, start, end - start);
        int i = start, j = mid, k = start;
        while (i < mid && j < end) {
            if (copy[i] <= copy[j]) {
                arr[k++] = copy[i++];
            } else {
                count += (mid - i);
                arr[k++] = copy[j++];
            }
        }
        while (i < mid) arr[k++] = copy[i++];
        while (j < end) arr[k++] = copy[j++];

        return count % MOD;
    }
}

Method 2: Fenwick tree

Maybe you want to add discrete would not write.

Fenwick tree principle of seeking the number of reverse order of
the first clear Fenwick tree maintenance information in this issue is the number of a section number that appears in the original source data according to their order of insertion Fenwick tree, the first idigit will insert way for the first tree of the array a[i]bit is set to 1, while the cover to its parent update interval, Query(a[i])can be obtained [ 1, a[i]]section and, on behalf of which just before the i-th number less than equal to its number, may only be equal to itself, so it has less than Query(a[i])-1one, then there is obviously greater than its i-1-(Query(a[i])-1) = i-Query(a[i])two

for (int i = 1; i <= n; i++) {
    Update(i, 1);
    ans += i - Query(a[i]);
}

int lowbit(int x) {
    return x & (-x);
}
void Update(int pos, int val) {
    for (int i = pos; i <= n; i += lowbit(i)) {
        c[i] += val;
    }
}
int Query(int pos) {
    int ans = 0;
    for (int i = n; i > 0; i -= lowbit(i)) {
        ans += c[i];
    }
    return ans;
}

Reference: https: //blog.csdn.net/Tc_To_Top/article/details/79562501

Number / Q37 number that appears in the sort array [binary search written analysis, equal_range ()]

The default is ascending.

Method 1: Handwritten binary search, and search for k-0.5 k + 0.5

(Note: If you find the number in the array exist, this dichotomy was written returns an error)

/**
 * 由于是有序数组中查找,考虑二分;
 * 由于是整数,所以可以稍微变一下,搜索k-0.5和k+0.5
 * 两个位置相减,即为k出现的次数
 */
public class Solution {
    public int GetNumberOfK(int [] array , int k) {
        if(array==null||array.length==0)
            return 0;
        return BiSearch(array, k+0.5) - BiSearch(array, k-0.5) ;
    }

    private int BiSearch(final int[] array,double x){
        // 返回第一个大于x的数的位置
        int left=0,right = array.length-1,mid;
        while(left<=right){
            mid= (right-left)/2+left;
            if(array[mid]<=x)// 如果需要的是第一个大于等于x的数的位置呢?
                left=mid+1;
            else
                right=mid-1;

        }
        return left;
    }
}

Writing binary idea analysis:
due to return to the first position is equal to a number greater than x, with the last leftdesignated as a target position, the initial range [0, array.length](because there is no return to find the array to the end). Lookup process, when
a[mid] <xwhen a[mid]the left target, left = mid+1
a[mid] >xwhen the a[mid]right of the target, right = mid-1;
a[mid]==x, the a[mid]possible target, the target may also be on the right, right = mid.
Finally, when the interval only two elements, if leftreferred to as the goal, rightleft, or leftright, to find the end of the two coincide.

Bipartite summary

Binary search task when looking for does not at the same time, left = mid or left = mid + 1 or right = mid or right = mid + wording 1 is different, to divide the discussion, the principle is the assignment left and right to ensure targets [left, right] the last, the length of interval of the case 2, and the loop end condition is given left <= right, or left <right.

//搜索k和k+1
public class Solution {
    public int GetNumberOfK(int [] array , int k) {
        if(array==null||array.length==0)
            return 0;
        return BiSearch(array, k+1) - BiSearch(array, k) ;
    }

    private int BiSearch(final int[] array,int x){
        // 返回第一个大于等于x的数的位置
        int left=0,right = array.length,mid;
        //为了使得当元素在数组中不存在时返回正确 right != array.length-1
        while(left<right){
            mid= (right-left)/2+left;
            if(array[mid]<x)
                left=mid+1;
            else
                right=mid;
        }
        return left;
    }
}

Method 2: C ++ STL equal_range ()

lower_bound(begin, end,val): Returns the first vessel is greater than or equal toval the element's position iterator.
upper_bound(begin, end, val): Returns the first vessel is greater than theval element iterator position.
binary_search(begin, end, val): Is there a return element is equal to the vessel val.
equal_range(begin, end, val): Return lower_boundand upper_boundthe pair.

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        auto resultPair = equal_range(data.begin(), data.end(),k);
        return resultPair.second - resultPair.first;
    }
};

// Q40 find out only once digital [] array of two-bit computing

In addition to an array of integers in two numbers, the other numbers appear twice. Please write a program to find these two figures appear only.

We know that if there is only one number appears once, then all elements XOR result is the number.
In this problem, all elements of the exclusive OR result of the exclusive OR of two numbers. Obviously, we can not derive the original number from the XOR result of two numbers.
However, if the exclusive-OR bit is a binary 1, a certain number of differences in the two bit, whereby the number of the array is divided into two categories, one of the bit is 0, the bit is a Class 1 , some are looking for two numbers in two categories. The number of categories respectively XOR, get the results.

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        if(array == null || array.length==1)
            return ;

        int xor = 0;
        for(int x:array){
            xor^=x;
        }

        if (xor == 0)
            return;

        int fisrtBit = (xor&(xor-1))^xor;// 结合上次学到的 n&(n-1) ,找到第一个为1 的bit ^. ^  ,或者 Xor&~(Xor - 1)
        
        num1[0]=num2[0]=0;
        for(int x:array){
            if((x&fisrtBit)!=0) num1[0]^=x;
            else num2[0]^=x;
        }
    }
}

Development: an array of a number appears only one time, other figures have appeared three times to find this number

Application of the 32 bit array, then the original array in each of a number into a binary expand, which is a 1, then bits [] +1 the one that eventually, each bit determines whether a multiple of 3 (or 0), if it is, then we are looking at the numbers this one certainly is zero, otherwise 1

/**
     * 数组a中只有一个数出现一次,其他数字都出现了3次,找出这个数字
     * @param a
     * @return
     */
public static int find1From3(int[] a){
    int[] bits = new int[32];
    int len = a.length;
    for(int i = 0; i < len; i++){
        for(int j = 0; j < 32; j++){
            bits[j] = bits[j] + ( (a[i]>>>j) & 1);
        }
    }
    int res = 0;
    for(int i = 0; i < 32; i++){
        if(bits[i] % 3 !=0){
            res = res | (1 << i);
        }
    }
    return res;
}

/ Q50 array repeated digital auxiliary storage means [not]

All numbers in a length of n in the array are in the range 0 to n-1.
Some digital array is duplicated, but do not know how many numbers are duplicated. Do not know each digit is repeated several times. Please find an array of any one of the duplicate numbers.
For example, if the length of the input array 7 {2,3,1,0,2,5,3}, then the corresponding output of the first 2 repeating digits.

When after a number is accessed, may be provided at the corresponding value + n bits, then encountered after the same number, find the corresponding bit number has become greater than or equal to n, then this number can be returned directly.

public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        for( int i=0;i<length;i++){
            int val=numbers[i];
            if(val>=length) val-=length;
            if(numbers[val]>=length){
                duplication[0]=val;
                return true;
            }
            numbers[val]+=length;
        }
        
        return false;
    }
}

Q51 building product array

Given an array A [0,1, ..., n- 1], please construct an array B [0,1, ..., n- 1], where B is the element B [i] = A [ 0] A [. 1] ... A [-I. 1] A [I +. 1] ... A [n--. 1]. You can not use the division.

First ride along, ride backwards again.

public class Solution {
    public int[] multiply(int[] A) {
        int[] B = new int[A.length];
        if (B.length != 0) B[0] = 1;
        for (int i = 1; i < B.length; i++) {
            B[i] = B[i - 1] * A[i - 1];
        }

        int temp = 1;
        for (int j = B.length - 2; j >= 0; j--) {
            temp *= A[j + 1];
            B[j] *= temp;
        }
        return B;
    }
}

Guess you like

Origin www.cnblogs.com/weseewe/p/11726881.html