2012-03-13 36 views
5

Đây là một vấn đề thú vị mà tôi đã thấy rằng tôi cảm thấy cần phải có một giải pháp thanh lịch, có thể chứng minh được nhưng tôi vẫn chưa thể có được nó. Tôi đã xác định nó như là:Các yếu tố khoảng cách trong một mảng tròn

Xác định một hàm mang theo như là đầu vào một loạt các yếu tố N và một dương nguyên R, và trả về một mảng tròn (hoặc một mảng mà bạn điều trị như hình tròn), nơi không hai phần tử giống hệt nhau cách nhau ít hơn R hoặc không có giá trị rỗng nếu không có thứ tự như vậy.

Vì vậy f([a,b,d,c,a,d,k,a,d], 3) có thể trở [a,b,d,a,k,d,a,c,d], nhưng f([a,b,d,c,a,d,k,a,d,a,a], 3) sẽ trở null. Tôi xác định hai phần tử là R apart nếu chúng có các phần tử R-1 giữa chúng, do đó, trong mảng [x,a,b,y], xy cách nhau 3 mặt và cách nhau 0 mặt.

Tôi cảm thấy đây cũng là một câu hỏi phỏng vấn tuyệt vời.

+0

@ EvgenyKluev- khi tôi đồng ý rằng tình trạng của bạn là đủ để có được không trật tự, nó là cần thiết? Ngoài ra, bạn có thể sử dụng cách tiếp cận của bạn để tạo ra một trật tự khi một tồn tại? – templatetypedef

+0

@ EvgenyKluev- Tôi không chắc tôi hiểu ý bạn là gì. Tôi không thấy cách sắp xếp mảng có thể tạo ra giải pháp làm việc khi có một mảng, cũng không thấy lý do tại sao sắp xếp mảng và lưu ý rằng không có quá nhiều bản sao của một phần tử đảm bảo rằng có cách sắp xếp các yếu tố. Bạn có thể xây dựng? – templatetypedef

+0

@templatetypedef, tôi hiểu nhầm câu hỏi. Lấy làm tiếc. –

Trả lời

3
  1. Chia mảng thành các nhóm các phần tử giống hệt nhau (bằng cách sắp xếp hoặc sử dụng thẻ bắt đầu bằng #).
  2. Tìm nhóm lớn nhất. Nếu kích thước của nó lớn hơn floor(N/R), trả về giá trị rỗng.
  3. Nếu kích thước của nhóm lớn nhất bằng chính xác N/R, phân vùng (sắp xếp một phần) danh sách nhóm, sao cho tất cả các nhóm có kích thước N/R trở thành bước đầu tiên trong bước sau.
  4. Đối với mỗi nhóm, hãy đặt các phần tử của nó vào mảng kết quả (bộ đệm tròn), chỉ số tăng thêm R, trong khi có thể. Nếu RN không phải là đồng tố, đôi khi - sau khi gia tăng N/GCD(N,R) - chỉ mục sẽ trỏ đến phần tử đã được sử dụng. Trong các trường hợp tăng chỉ số này bằng R+1 thay vì R và tiếp tục.
+0

Bạn có chắc chắn rằng nó hoạt động chính xác không? Tôi nghĩ bạn nói đúng, nhưng tôi không tin 100% rằng điều này sẽ không đưa ra quyết định tối ưu cục bộ mà là tối ưu trên toàn cầu. – templatetypedef

+0

@B_. - xin lỗi, nhưng tôi không hiểu phản đối của bạn. Tôi đã thực hiện những gì tôi hiểu từ trên và trình tự hoạt động ok (tôi nghĩ?). xin vui lòng xem câu trả lời của tôi ở đây cho mã. –

+0

Đã xóa nhận xét trước của tôi vì nó bật ra tôi đã hiểu sai một chút câu trả lời này. Tôi đang đánh dấu nó đúng bởi vì tôi không thể tìm thấy một counterexample (cảm ơn andrew), mặc dù tôi sẽ cố gắng sau này để thực hiện một bằng chứng chính thức của nó. –

1

Tôi cảm thấy hơi nóng tính ở đó. Tôi không làm điều này cho điểm. Tôi làm điều đó vì tôi thích nó. Tôi đã cho bạn rất nhiều và nghĩ rằng bạn sẽ có thể thực hiện thông qua của riêng bạn. Dù sao, đây là một nơi mà những người lạ hoàn toàn giúp đỡ những người lạ hoàn toàn.

Đây là một mã, với kết quả của các xét nghiệm sau đây:

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))); 
} 
} 

Kết quả kiểm tra:

[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] 
+0

Đây là một cách thực hiện tương tự với Evgeny được đề xuất và gặp phải các vấn đề tương tự. –

+0

Tôi đọc câu trả lời bạn đề cập đến. Nó khác với tôi ở chỗ nó không luôn luôn reinsert nhóm lớn nhất đầu tiên, mà sẽ là một vấn đề trong nhiều ví dụ. Tôi sẽ chạy trong bộ đầu vào. – kasavbere

+0

Bạn nói đúng về phần đó. –

0

Cảnh báo: Đây không phải là một giải pháp. Nó chỉ là một sự cải cách.

Để khắc phục ký hiệu, hãy nói rằng có m các loại phần tử khác nhau (có thể gọi sau đó là 1,2,...,m) và có a_i yếu tố thuộc loại i. Sau đó, chúng tôi có a_1 + ... + a_m = N.

Hãy G(N,R) là đồ thị với các đỉnh v1, v2, ..., vN nơi có một cạnh vi <--> vj bất cứ khi nào |i-j| mod N < R. Ví dụ: G(N,2)N -cycle. Câu hỏi yêu cầu một số proper coloring của N -cycle với a_i các đỉnh màu i.

Trong ngữ cảnh này, câu hỏi tương đương với việc tính toán các hệ số không đồng bộ của Stanley's chromatic symmetric function. Điều này có thể không làm cho vấn đề trở nên dễ dàng hơn, nhưng nó chắc chắn làm cho nó thú vị hơn trong tâm trí của tôi. Ví dụ, tôi tin rằng câu trả lời được biết đến với G(N,2), một cái gì đó giống như nó tồn tại iff max(a_i) <= N/2 (chắc chắn không có giải pháp tồn tại nếu có bất kỳ a_i > N/R). Tôi sẽ cập nhật câu trả lời này sau khi nghiên cứu thêm một chút.

2

Tôi xin lỗi, tôi cảm thấy câm ở đây, nhưng tôi không hiểu sự phản đối của giải pháp của Evgeny. tôi nghĩ rằng đoạn code dưới đây thực hiện những gì họ đề nghị (ngoại trừ tôi ném một lỗi hơn là trả về null) và hoạt động tốt với trình tự được cho là có vấn đề.

Tôi đăng câu trả lời này chủ yếu là vì tôi muốn đăng mã để sửa. có lẽ nó có cùng một vấn đề như câu trả lời trước đó, vì vậy xin vui lòng ai đó có thể giải thích vấn đề là gì?

(trong trường hợp của tôi, các nhóm cũng được sắp xếp theo độ dài, không được đưa ra trước đó).

from collections import Counter, defaultdict 

def ring(n, text): 
    result = [None for t in text] 
    index = 0 
    for c in Counter(text).elements(): 
     while result[index] is not None: 
      index = (index + 1) % len(result) 
     result[index] = c 
     index = (index + n) % len(result) 
    loop = ''.join(result) 
    print(text, ' -> ', loop) 
    check(n, loop) 

def check(n, text): 
    loop = text + text 
    last = defaultdict(lambda: -n) 
    for (i,c) in enumerate(loop): 
     assert i - last[c] >= n, (c, i - last[c]) 
     last[c] = i 

ring(3, 'aaaabbbcccdd') # problematic according to B_? 
ring(3, 'abdcadkad') # given in question 
ring(3, 'abdcadkadaa') # given in question, expected to fail 

và chạy:

> python3.2 ring.py 
aaaabbbcccdd -> acbacbacdabd 
abdcadkad -> akdacdabd 
abdcadkadaa -> aadakdacdab 
Traceback (most recent call last): 
    File "ring.py", line 25, in <module> 
    ring(3, 'abdcadkadaa') 
    File "ring.py", line 14, in ring 
    check(n, loop) 
    File "ring.py", line 20, in check 
    assert i - last[c] >= n, (c, i - last[c]) 
AssertionError: ('a', 1) 
+0

Vâng, bạn sẽ đưa ra một thứ tự tốt cho những ví dụ đó. Sự khác biệt giữa cách tôi đã thực hiện nó (tôi đã nghĩ về kế hoạch đó) và của bạn là đối với mỗi tập hợp các phần tử trùng lặp mới, tôi bắt đầu lại ở đầu danh sách thay vì tiếp tục từ bất cứ đâu. Tôi không thấy chính xác lý do tại sao giải pháp của bạn sẽ làm việc cho tất cả các yếu tố đầu vào khi giải pháp đó không, vì vậy tôi sẽ tiếp tục xem xét nó. Cảm ơn! –

+0

ah, ok. không, điều đó sẽ không hiệu quả. nhưng tôi cũng không có bằng chứng chính thức cho điều này. –

+0

bằng cách xây dựng khoảng cách giữa các chữ cái tương tự luôn là yêu cầu tối thiểu hoặc một số khác. vấn đề duy nhất là khi bạn thực hiện toàn bộ vòng lặp, với bước nhảy "thêm một" ở giữa. sau đó bạn có thể có một vấn đề nếu nhảy đó đẩy "kết thúc" với nhau. tôi nghĩ một bằng chứng chỉ cần liệt kê những trường hợp đó. nhưng tôi đi ngủ ... –

Các vấn đề liên quan