
7-2. Fish
You are given two non-empty arrays A and B consisting of N integers. Arrays A and B represent N voracious fish in a river, ordered downstream along the flow of the river.
The fish are numbered from 0 to N − 1. If P and Q are two fish and P < Q, then fish P is initially upstream of fish Q. Initially, each fish has a unique position.
Fish number P is represented by A[P] and B[P]. Array A contains the sizes of the fish. All its elements are unique. Array B contains the directions of the fish. It contains only 0s and/or 1s, where:
0 represents a fish flowing upstream,
1 represents a fish flowing downstream.
If two fish move in opposite directions and there are no other (living) fish between them, they will eventually meet each other. Then only one fish can stay alive − the larger fish eats the smaller one. More precisely, we say that two fish P and Q meet each other when P < Q, B[P] = 1 and B[Q] = 0, and there are no living fish between them. After they meet:
If A[P] > A[Q] then P eats Q, and P will still be flowing downstream,
If A[Q] > A[P] then Q eats P, and Q will still be flowing upstream.
We assume that all the fish are flowing at the same speed. That is, fish moving in the same direction never meet. The goal is to calculate the number of fish that will stay alive.
For example, consider arrays A and B such that:
A[0] = 4 B[0] = 0
A[1] = 3 B[1] = 1
A[2] = 2 B[2] = 0
A[3] = 1 B[3] = 0
A[4] = 5 B[4] = 0
Initially all the fish are alive and all except fish number 1 are moving upstream. Fish number 1 meets fish number 2 and eats it, then it meets fish number 3 and eats it too. Finally, it meets fish number 4 and is eaten by it. The remaining two fish, number 0 and 4, never meet and therefore stay alive.
Write a function:
class Solution { public int solution(int[] A, int[] B); }
that, given two non-empty arrays A and B consisting of N integers, returns the number of fish that will stay alive.
For example, given the arrays shown above, the function should return 2, as explained above.
Write an efficient algorithm for the following assumptions:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [0..1,000,000,000];
each element of array B is an integer that can have one of the following values: 0, 1;
the elements of A are all distinct.
두 개의 비어 있지 않은 배열 A와 B가 N개의 정수로 구성되어 있습니다. 배열 A와 B는 강에서 N마리의 탐욕스러운 물고기를 나타내며, 강의 흐름을 따라 하류로 정렬되어 있습니다.
물고기는 0부터 N-1까지 번호가 매겨져 있습니다. 만약 P와 Q가 두 마리의 물고기이고 P < Q라면, 물고기 P는 처음에 물고기 Q의 상류에 있습니다. 처음에는 각 물고기가 고유한 위치를 가지고 있습니다.
물고기 번호 P는 A[P]와 B[P]로 나타냅니다. 배열 A는 물고기의 크기를 포함하고 있습니다. 모든 요소는 고유합니다. 배열 B는 물고기의 방향을 포함하고 있습니다. 0과 1만 포함하고 있으며:
0은 상류로 흐르는 물고기를 나타냅니다.
1은 하류로 흐르는 물고기를 나타냅니다.
두 물고기가 반대 방향으로 움직이고 그들 사이에 다른 (살아있는) 물고기가 없다면, 결국 서로 만나게 됩니다. 그러면 한 마리의 물고기만 살아남을 수 있습니다. 더 큰 물고기가 더 작은 물고기를 먹습니다. 더 정확히 말하면, 두 물고기 P와 Q가 서로 만난다고 할 때, P < Q, B[P] = 1, B[Q] = 0이고 그들 사이에 살아있는 물고기가 없을 때입니다. 그들이 만난 후:
만약 A[P] > A[Q]라면 P가 Q를 먹고, P는 여전히 하류로 흐릅니다.
만약 A[Q] > A[P]라면 Q가 P를 먹고, Q는 여전히 상류로 흐릅니다.
모든 물고기는 동일한 속도로 흐른다고 가정합니다. 즉, 같은 방향으로 움직이는 물고기는 절대 만나지 않습니다. 목표는 살아남을 물고기의 수를 계산하는 것입니다.
예를 들어, 다음과 같은 배열 A와 B를 고려해보세요:
A[0] = 4 B[0] = 0
A[1] = 3 B[1] = 1
A[2] = 2 B[2] = 0
A[3] = 1 B[3] = 0
A[4] = 5 B[4] = 0
처음에는 모든 물고기가 살아있고, 물고기 번호 1을 제외한 모든 물고기가 상류로 이동합니다. 물고기 번호 1은 물고기 번호 2를 만나서 먹고, 그 다음 물고기 번호 3을 만나서 먹습니다. 마지막으로 물고기 번호 4를 만나서 먹힙니다. 남은 두 마리의 물고기, 번호 0과 4는 서로 만나지 않으므로 살아남습니다.
다음과 같은 함수를 작성하세요:
class Solution {
public int solution(int[] A, int[] B);
}
두 개의 비어 있지 않은 배열 A와 B가 N개의 정수로 구성되어 있을 때, 살아남을 물고기의 수를 반환합니다.
예를 들어, 위에서 보여준 배열이 주어지면 함수는 2를 반환해야 합니다.
다음 가정을 위한 효율적인 알고리즘을 작성하세요:
N은 [1…100,000] 범위 내의 정수입니다.
배열 A의 각 요소는 [0…1,000,000,000] 범위 내의 정수입니다.
배열 B의 각 요소는 0 또는 1 값을 가질 수 있습니다.
배열 A의 요소는 모두 고유합니다.
문제풀이
import java.util.*;
class Solution {
public int solution(int[] A, int[] B) {
int fishs = 0;
Stack<Integer> downfish = new Stack<>();
for (int i = 0; i < A.length; i++) {
if (B[i] == 1) { // 1일 경우(하류)
downfish.push(A[i]);
} else { // 0일 경우(상류)
while (!downfish.isEmpty()) {
if (downfish.peek() > A[i]) {
break;
} else {
downfish.pop();
}
}
if (downfish.isEmpty()) {
fishs++;
}
}
}
fishs += downfish.size();
return fishs;
}
}
하류로 흐르는 물고기(B[i] == 1)는 스택에 추가
상류로 흐르는 물고기(B[i] == 0)를 만날 때, 스택에서 하류로 흐르는 물고기를 꺼내어 크기를 비교하여 더 큰 물고기가 살아남고, 작은 물고기는 제거합니다.
모든 물고기를 처리한 후, 스택에 남아 있는 하류로 흐르는 물고기와 상류로 흐르는 물고기의 수를 합하여 최종 결과를 반환
제출결과

문제풀어보기 -> https://app.codility.com/programmers/lessons/7-stacks_and_queues/fish/