圆形阵列中的间距元素

时间:2012-03-13 16:59:06

标签: arrays algorithm

这是一个我遇到的一个有趣的问题,我觉得应该有一个优雅,可证明的解决方案,但我还没有完全得到它。我把它定义为:

  

定义一个函数,该函数将N个元素和a的数组作为输入   正整数R,并返回一个圆形数组(或您的数组)   视为圆形),其中没有两个相同的元素小于R.   如果没有这样的排序,则为null。

因此f([a,b,d,c,a,d,k,a,d], 3)可能会返回[a,b,d,a,k,d,a,c,d],但f([a,b,d,c,a,d,k,a,d,a,a], 3)会返回null。我将两个元素定义为R apart,如果它们之间有R-1个元素,那么在数组[x,a,b,y]中,xy一边是3个而在另一方面则相隔0。

我觉得这也是一个很棒的面试问题。

3 个答案:

答案 0 :(得分:3)

  1. 将数组拆分为相同元素的组(使用排序或使用哈希表)。
  2. 找到最大的一组。如果其大小大于floor(N/R),则返回null。
  3. 如果最大组的大小恰好等于N/R,则对组列表进行分区(部分排序),以便所有大小为N/R的组在后续步骤中排在第一位。
  4. 对于每个组,将其元素放入结果数组(循环缓冲区),将索引递增R,尽管可能。如果RN不是共同素数,有时 - 在N/GCD(N,R)增量之后 - index将指向已使用的元素。在这种情况下,请按R+1而不是R增加索引并继续。

答案 1 :(得分:1)

我觉得那里有点脾气。我不是为了积分而这样做的。我这样做是因为我喜欢它。我给了你很多,并认为你可以自己完成。无论如何,这是一个完全陌生人帮助完成陌生人的地方。

这是一段代码,测试结果如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ResolvingAlgo {

public static Character[] resolver(Character[] objects, int R) {
    //calculate frequency of each element
    Map<Character, Integer> map = new HashMap<Character, Integer>();
    for (Character c : objects) {
        Integer freq = map.get(c);
        map.put(c, (freq == null) ? 1 : freq + 1);
    }
    //count elements with frequency R
    List<Character> pillars = new ArrayList<Character>();
    for (Character c : map.keySet()) {
        int freq = map.get(c);
        if (R == freq) {
            pillars.add(c);
        } else if (objects.length/R < freq) {
            return null;
        }
    }
    //output array
    Character output[] = new Character[objects.length];
    //load the pillars R+1 apart
    int skip = (pillars.size()<R)?R:R+1;
    for (Character c : pillars) {
        int index = 0;
        for (int out=index; out<output.length; out++) {
            if (output[out] == null) {
                break;
            }
            index++;
        }
        for (int i = R; i > 0; i--) {
            output[index] = c;
            index += skip;
        }
        map.remove(c);
    }//pillars
    //add remainders
    while (!map.isEmpty()) {
        int index = 0;
        Character keyset[] = Arrays.copyOf(map.keySet().toArray(new Character[0]), map.size());
        for (Character c : keyset) {
            for (int out = index; out < output.length; out++) {
                if (null == output[out]) {
                    break;
                }
                index++;
            }
            output[index] = c;
            int freq = map.get(c);
            if (freq <= 1) {
                map.remove(c);
            } else {
                map.put(c, freq - 1);
            }
        }//for keyset
    }//while
    return output;
}//resolver

public static void main(String... args) {
    Character[][] input = {
        {'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'},
        {'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'k'},
        {'a', 'a', 'a', 'b', 'c', 'd', 'd', 'd', 'k'},
        {'a', 'b', 'd', 'c', 'a', 'd', 'k', 'a', 'd', 'a', 'a'},
        {'a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'},
        {'a', 'b', 'c', 'd', 'e', 'f', 'a', 'b', 'c', 'd', 'e', 'f'},
        {'a','b','c','d','a','b','c','d'}
    };
    for(Character in[]: input)
        System.out.println(Arrays.toString(resolver(in, 3)));
}
}

测试结果:

[d, b, c, a, d, b, c, a, d, b, c, a]
[b, c, a, d, b, c, a, k, b, c, a, d]
[d, a, b, d, a, c, d, a, k]
null
[b, c, d, b, c, a, b, c, d, a, a, a]
[f, d, e, b, c, a, f, d, e, b, c, a]
[d, b, c, a, d, b, c, a]

答案 2 :(得分:0)

警告:这不是解决方案。这只是一个重新制定。

要修复表示法,请说m个不同类型的元素(可以调用1,2,...,m),a_i个元素i。然后我们有a_1 + ... + a_m = N

G(N,R)成为顶点为v1, v2, ..., vN的图形,其中只要vi <--> vj存在边|i-j| mod N < R。例如,G(N,2)N - 周期。该问题要求N - proper coloring周期a_i个顶点为i

在此上下文中,该问题等同于计算Stanley's chromatic symmetric function的非零系数。这可能不会使问题变得更容易,但它肯定会让我觉得更有趣。例如,我相信G(N,2)的答案是已知的,如果存在if max(a_i) <= N/2(当然,如果有a_i > N/R则不存在解决方案)。经过一番研究后,我会更新这个非答案。