通过一个具体的例子来理解Big-O.

时间:2018-05-14 23:56:44

标签: algorithm big-o analysis pseudocode

我正在研究一个相当简单的问题,以确保我理解这些概念。

问题是:存在n个元素的数组A,可以是RED,WHITE或BLUE。重新排列数组,使所有WHITE元素都在所有BLUE元素之前,并且所有BLUE元素都在所有RED元素之前。在O(n)时间和O(1)空间构造算法。

根据我的理解,解决方案的伪代码将是:

numW = numB = 0
for i = 0 to n:
    if ARRAY[i] == WHITE:
        numW++
    else if ARRAY[i] == BLUE:
        numB++

for i = 0 to n:
    if numW > 0:
        ARRAY[i] = WHITE
        numW--
    else if numB > 0:
        ARRAY[i] = BLUE
        numB--
    else:
        ARRAY[i] = RED

我认为它是O(n)因为它遍历循环两次而O(2n)在O(n)中。我认为空间是O(1),因为它不依赖于元素的总数,即每个元素总是有计数

我的理解是否正确?

3 个答案:

答案 0 :(得分:1)

如果它是线性时间,并且你的算法似乎是,那么它就像你怀疑的那样是O(n)。这里有一个很棒的摘要:Big-O for Eight Year Olds?

答案 1 :(得分:1)

是的,您的解决方案在O(1)空间的O(n)时间内运行。

下面是我的解决方案,它也在O(n)时间和O(1)空间中运行,但在我们引用对象时也可以工作,如@kenneth在评论中建议的那样。

import java.util.Arrays;
import java.util.Random;
import static java.lang.System.out;

class Color{
    char c;
    Color(char c){
        this.c = c;
    }
}

public class Solution {

    private static void rearrangeColors(Color[] collection){
        int ptr = 0;   

        // move all whites to the left

        for(int i=0;i<collection.length;++i){
            if(collection[i].c == 'W'){
                swap(collection,ptr,i);
                ptr++;
            }
        }

        // move all blacks to the left after white       

        for(int i=ptr;i<collection.length;++i){
            if(collection[i].c == 'B'){
                swap(collection,ptr,i);
                ptr++;
            }
        }
    }

    private static void swap(Color[] collection,int ptr1,int ptr2){
        Color temp = collection[ptr1];
        collection[ptr1] = collection[ptr2];
        collection[ptr2] = temp;
    }

    private static void printColors(Color[] collection){
        for(int i=0;i<collection.length;++i){
            out.print(collection[i].c + ( i != collection.length - 1 ? "," : ""));
        }
        out.println();
    }

    public static void main(String[] args) {
        // generate a random collection of 'Color' objects
        Random r = new Random();
        int array_length = r.nextInt(20) + 1;// to add 1 if in case 0 gets generated 
        Color[] collection = new Color[array_length];
        char[] colors_domain = {'B','W','R'};

        for(int i=0;i<collection.length;++i){
            collection[i] = new Color(colors_domain[r.nextInt(3)]);
        }

        // print initial state
        printColors(collection);
        // rearrange them according to the criteria
        rearrangeColors(collection);
        // print final state
        printColors(collection);        
    }

}

答案 2 :(得分:0)

我不会说这是100%正确,但这里的快速测试案例确实有效。如果有的话,它表明能够一次性完成它的想法。它更快吗?可能不是。对于这种情况,我认为OP的答案仍然是最好的。

#include <stdio.h>

char temp;
#define SWAP(a,b) { temp = a; a = b; b = temp;}

int main()
{
    int n = 10;
    char arr[] = "RWBRWBRWBR";
    printf("%s\n", arr);

    int white = 0;

    for(int i=0; i<n; i++)
    {
        if(arr[i] == 'B')
        { 
            SWAP(arr[i], arr[n-1]);
            i--; n--;
        }
        else if(arr[i] == 'R')
        {
            SWAP(arr[i], arr[white]);
            white++;
        }
    }

    printf("%s\n", arr);
}