[Smart Solution] Count the number of occurrences of each element of an unordered array - time complexity O(n), space complexity O(1)

1. Problem description

An array of length n, each element in the array has a value in the range [1,n] and is a positive integer.
Question: How to count the number of occurrences of different elements in an array under the condition that the time complexity is O(n) and the space complexity is O(1).

2. Problem-solving ideas

    The array is scanned in order, and the value of the current element is used as a subscript to find the next element. In the resulting array, the subscript (because the subscript starts from 0, so it needs +1 when outputting) is the element that appears in the array, and the inverse output of the value corresponding to each subscript is the frequency of the element.
    If the current element is less than 0,
        skip it;
    if the current element is greater than 0,
        judge whether the element indexed by it as a subscript is greater than 0,
            if it is greater than 0, the indexed element is assigned to the current element, and the indexed element is set to -1;
            if it is less than 0, the indexed element is decremented by 1, and the current element is set to 0;

     positive/negative numbers are used to distinguish whether a[i] is the original value or the value used for counting.
    For example, For example, { 2, 5, 5, 2, 3 }
    sees that the first one is 2, that is, 2 has 1, so first save this "1" to the position of a[2-1]. But a[2-1] has a significant number, what should I do? Just move it. Suppose I don't use negative numbers, but use square brackets to represent counts, and the steps are
    { 2, 5, 5, 2, 3 }
    5, [1], 5, 2, 3
    3, [1], 5, 2, [ 1]
    5, [1], [1], 2, [1]
    [0], [1], [1], 2, [2]
    [0], [2], [1], [0], [2]

    The result is 1 has 0, 2 has 2, 3 has 1, 4 has 0, 5 has 2

    Such methods of subscripting apply conditions:

  •     positive integer
  •     Value range [1,n]
  •     n numbers

3. Algorithm code

#include <stdio.h>
#include <stdlib.h>
/*******************************
Author:tmw
date:2018-3-17
********************************/
int* mark_times_apear( int* array, int n )
{
    if( n==0 || !array )
        return NULL;

    int i=0;
    while( i<n )
    {
        int target_index = array[i]-1; //array index starts from 0
        /**
        When the current element to be exchanged is a valid bit (a negative number greater than the count value), exchange,
        and change the value under the element to be swapped to a negative count value
        **/
        if( array[target_index]>0 )
        {
            array[i] = array[target_index];
            array[target_index] = -1;
        }
        if( target_index<0 )
        {
            i++;
            continue;
        }
        /**
        The remaining cases are:
            array[target_index]<=0 || target_index>=0 || both
            That is: the element has appeared once, and negative counts require -- to update the record
        **/
        else
        {
            array[target_index]--;
            array[i] = 0;
        }
    }
    return array;
}

4. Test code and results

intmain()
{
    printf("Test code!\n");

    int* array;
    int i;
    array = (int*)malloc(5*sizeof(int));
    printf("Please enter 5 array elements:\n");
    for( i=0;i<5;i++ )
        scanf("%d",&array[i]);
    array = mark_times_apear(array,5);

    for( i=0;i<5;i++ )
        printf("%d ",array[i]);

    return 0;
}


There is still a dream, if it comes true~~~ヾ(◍°∇°◍)ノ゙~~~

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325908348&siteId=291194637