我正在尝试解决下面所述的Hackerrank问题Non-Divisible Subset:
我尝试了以下解决方案(适用于示例测试用例):
# The lines below are for Hackerrank submissions
# n, k = map(int, raw_input().strip().split(' '))
# a = map(int, raw_input().strip().split(' '))
n = 4
k = 3
a = [1, 7, 2, 4]
while True:
all_pairs = [(a[i],a[j]) for i in range(len(a)) for j in range(i+1,len(a))]
tested_pairs = {pair: (pair[0] + pair[1]) % k != 0 for pair in all_pairs}
disqualified_pairs = {key: value for key, value in tested_pairs.iteritems() if not value}.keys()
if not disqualified_pairs:
break
occurrences = list(sum(disqualified_pairs, ()))
counts = map(lambda x: occurrences.count(x), a)
index_remove = counts.index(max(counts))
a.remove(index_remove)
print len(a)
我要做的是确定'违规'对并删除最常出现的a
元素,直到没有'冒犯'对为止。
但是,对于大多数测试用例,我得到“运行时错误”:
据推测,上述算法适用于这种简单的情况,其中只需要删除一个数字(数字2),但在更复杂的测试用例中失败。有人能看出它有什么问题吗?
更新
根据poke的建议来测试k = 2
和a = [1, 2, 3]
,我做了以下修改:
n = 4
k = 2
a = [1, 2, 3]
while True:
all_pairs = [(a[i],a[j]) for i in range(len(a)) for j in range(i+1,len(a))]
disqualified_pairs = [pair for pair in all_pairs if (pair[0] + pair[1]) % k == 0]
if not disqualified_pairs:
break
offending_numbers = sum(disqualified_pairs, ()) # 'Flatten' the disqualified pairs into a single list
counts = {el: offending_numbers.count(el) for el in set(offending_numbers)} # Count occurrences of each offending number
number_to_remove = max(counts, key=counts.__getitem__)
a.remove(number_to_remove)
print len(a)
生成的a
为[2, 3]
,并按预期包含两个元素。我还检查过它仍适用于原始示例。但是,我仍然在某些测试用例中遇到“分段错误”:
根据https://www.hackerrank.com/challenges/pairs/forum/comments/9154,由于无效的内存访问(不存在的数组索引等),通常会发生分段错误。但是,在算法失败的情况下,我仍然没有找到任何其他测试用例。有什么想法吗?
答案 0 :(得分:2)
这可以通过计算模数来完成,而不是生成所有对。
时间复杂度:O(n + k)
空间复杂度:O(k)或O(1),因为k最大为100,O(k)=> O(1)
基本理念
(a + b)%k =((a%k)+(b%k))%k
因为(a%k)在[0,k-1]范围内,
(a%k)+(b%k)在[0,2k-2]
的范围内
此外,
(a + b)%k = 0
(a%k)= 0且(b%k)= 0 OR
- 醇>
(a%k)+(b%k)= k
主要想法
根据以上信息,解决方案可能是
答案 1 :(得分:1)
我使用的方法是:
1. find power set of given list of integers.
2. sort power set by subset size.
3. iterate down the sorted power set and print if subset meets problem's conditions.
在java中:
import java.util.*;
public class f implements Comparator<List<?>> {
@Override
public int compare(List<?> o1, List<?> o2) {
return Integer.valueOf(o1.size()).compareTo(o2.size());
}
static ArrayList<ArrayList<Integer>> powerSet = new ArrayList<>();
// get power set of arr
static void g(int arr[],int[] numbers,int i){
if(i==arr.length){
ArrayList<Integer> tmp = new ArrayList<>();
for(int j = 0;j<arr.length;j++){
if(arr[j]==1) tmp.add(numbers[j]);
}
powerSet.add(tmp);
return;
}
arr[i] = 1;
g(arr,numbers,i+1);
arr[i] = 0;
g(arr,numbers,i+1);
}
static void h(int[] a){
int[] arr=new int[a.length];
for(int j =0;j<arr.length;j++){
arr[j]=0;
}
g(arr,a,0);
}
// check whether the sum of any numbers in subset are not evenly divisible by k
static boolean condition(ArrayList<Integer> set,int k){
for(int i = 0;i<set.size();i++){
for(int j = i+1;j<set.size();j++){
if((set.get(i)+set.get(j))%k==0){
return false;
}
}
}
return true;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int k = in.nextInt();
int[] a = new int[n];
for (int i=0;i<n;i++){
a[i]=in.nextInt();
}
h(a);
Collections.sort(powerSet, new f());
for(int i=powerSet.size()-1;i>0;i--){
if(condition(powerSet.get(i),k)){
System.out.println(powerSet.get(i).size());
break;
}
}
}
}
结果: 测试用例#9错误是StackOverflowError:
的结果不熟悉hackerrank错误,但也许你的错误类似。