我有两个数组A
和B
。我必须找到数组C
所需的元素数量以适应特定的长度。
Length = B[i]-A[i]
例如:
A[0] = 1 B[0] = 4
A[1] = 4 B[1] = 5
A[2] = 5 B[2] = 9
A[3] = 8 B[3] = 10
and
C[0] = 4
C[1] = 6
C[2] = 7
C[3] = 10
C[4] = 2
答案是4
。
说明:
C[0] is falling in the range of (A[0],B[0]) and (A[1],B[1])
C[1] is falling in the range of (A[2],B[2])
C[2] is of no use
C[3] is falling in the range of (A[3],B[3])
so the total is 4
我的方法:
传统方法:简单循环数组C
中A
的每个元素,如果在范围内找到,则将A[i]
和B[i]
的值设置为减去无限或删除它们(对于Arraylist)。
HashTable :将哈希表中的值存储为A[i]
作为键,将B[i]
存储为值。然后找到给定C[i]
的元素并删除密钥。我认为这不是一个好方法
请为我提供一个有效的算法。
答案 0 :(得分:1)
好的,基于你的答案,我们别无选择,只能检查C的每个元素对A和B.但由于A和B按升序排列,性能应该是合理的:
int len = A.length;
boolean[] eliminated = new boolean[len]; // initially all elements are false
int totalEliminated = 0;
for (int i = 0; i < C.length; i++) {
int c = C[i];
for (int j = 0; j < len && A[j] <= c; j++) {
if (B[j] >= c && !eliminated[j]) {
System.out.println(c + " eliminates " + A[j] + " - " + B[j]);
eliminated[j] = true;
if (++totalEliminated == len) {
return i+1;
}
}
}
}
return 0;
答案 1 :(得分:1)
如果输入范围已从最小到最大排序(B [i] <= A [i + 1]):
int bottomRangeIndex = 0;
int topRangeIndex = numberOfABRangesYouHave - 1;
int answerCounter = 0;
C.sort(); // Sort C so that it goes from smallest to largest number.
for number in C: {
if (number < A[bottomRangeIndex]) {
continue;
} else if (number > B[topRangeIndex]) {
return answerCounter;
} else {
while ((number > B[bottomRangeIndex++]) && (bottomRangeIndex <= topRangeIndex)) {
// Just keeps incrementing bottomRangeIndex.
}
if (bottomRangeIndex > topRangeIndex) {
return answerCounter;
} else {
answerCounter++;
bottomRangeIndex++;
}
}
}
这可能有一些我没想到的错误,但基本上它的作用是:
试试这个,看它是否有效。如果这是家庭作业,你真的不能对C进行排序,那么你可以通过少量的调整来修改它以给你正确的答案,但我不会说如何......
答案 2 :(得分:1)
这是使用ArrayLists的更高效版本:
int len = arrA.length;
ArrayList<Integer> A = new ArrayList<Integer>(len);
ArrayList<Integer> B = new ArrayList<Integer>(len);
for (int i=0; i<len; i++) {
A.add(arrA[i]);
B.add(arrB[i]);
}
for (int i = 0; i < C.length; i++) {
int c = C[i];
int j = 0;
while (j<A.size() && A.get(j) <= c) {
if (B.get(j) >= c) {
A.remove(j);
if (A.isEmpty()) return i+1;
B.remove(j);
}
else {
j++;
}
}
}
return 0;
答案 3 :(得分:0)
这是在O(n log n)中解决它的一个快速草图。它可能不是实践中最好的方法,但只是为了提供一种n log n方法。
总而言之,这是一种全面的技术。或者更确切地说,在这种情况下。
1. Sort arrays A, B, and C (cost: n log n). Think of the arrays as queues
(that is, "remove" elements from the left by increasing a start index).
2. Create current-intervals set (initially empty. Has O(log n) operations.)
2. While A not empty or B not empty or C not empty:
3. get the lowest element from the first (if any) elements in A, B, and C.
4. if it's an A:
5. Add the corresponding interval to the current-intervals list
6. else if it's a B:
7. Remove the corresponding interval from the current-intervals list
8. else it must be a C, so:
9. The answer to the query corresponding to C is the current-intervals list
(in the current state)
答案 4 :(得分:0)
for(int i =0 ;i<C.length;i++)
for(int j=0;j<A.length;j++)
{
if(A[i]<=C[i] && B[i]>=C[i])
{ answer++;
A[i] = Integer.Max_Value;
}
}
会的 给你一个正确的答案
答案 5 :(得分:0)
我尝试了一些树形结构,但最终我又回到了一个简单的二元搜索,所以现在是O(nlogn):
static int getAnswerV2a(int[] A, int[] B, int[] C) {
int len = A.length;
ArrayList<Interval> intervals = new ArrayList<Interval>(len);
for (int i=0; i<len; i++) {
intervals.add(new Interval(A[i], B[i]));
}
for (int i = 0; i < C.length; i++) {
int c = C[i];
binarySearch(intervals, 0, intervals.size(), c);
if (intervals.isEmpty()) return i+1;
}
return -1;
}
static class Interval {
int start, end;
Interval(int start, int end) {
this.start = start;
this.end = end;
}
boolean matches(int c) {
return start <= c && c <= end;
}
}
// Find an interval (between indices i and j) that matches c
// When found, remove it from the List and adjust indices accordingly
static void binarySearch(ArrayList<Interval> intervals, int i, int j, int c) {
if (i==j)
return;
else if (i+1==j) {
if (intervals.get(i).matches(c))
intervals.remove(i);
}
else {
int mid = (int) Math.floor((i+j) / 2);
Interval interval = intervals.get(mid);
if (interval.start > c)
binarySearch(intervals, i, mid, c);
else if (interval.end < c)
binarySearch(intervals, mid+1, j, c);
else {
intervals.remove(mid);
binarySearch(intervals, i, j-1, c);
}
}
}