我正在研究一个相当简单的问题,以确保我理解这些概念。
问题是:存在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),因为它不依赖于元素的总数,即每个元素总是有计数
我的理解是否正确?
答案 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);
}