[질문 요구 사항] N 숫자와 n을 제공합니다. 이제 O (1) 내에서 O (N) 공간에서 시간의 50% 이상이 발생하는 숫자를 찾아야합니다.
[Bullshit 시작] 처음에, 나는이 질문이 즉시 눈을 멀게하는 것을 보았습니다 (tot)/~~~ (.*). O (n)의 시간 요구 사항 만 있으면 해시 (즉, 시간을위한 공간)로 즉시 해결할 수 있으며 O (1)의 공간을 해결하기가 어려워 보입니다.
[생각 1] 이중 루프, 이것은이 문제를 해결하는 가장 효율적인 방법입니다.
[생각 2] 첫 번째 정렬, 비슷한 숫자를 함께 배열 한 다음 첫 번째 숫자에서 통과하십시오. 이제 다음과 같은 예를 들어 다음과 같은 예를 들어 다음과 같은 예를 들어 다음과 같은 예를 들어, 이제 정렬 : 0000112, 0부터 시작하고, 카운터 t = 0을 설정하고, 이제 4 0, T = 4가 있고, 그 중 절반 이상, 출력 0을 찾으십시오.이 방법은 이전 방법의 최적화 된 버전입니다.
[생각 3] 1 차원 어레이를 만들기 위해 시간과 해시가 두 가지 의미를 갖도록하는 것이 아이디어입니다. 예를 들어, [x] = y는 숫자 x가 y 시간에 나타나는 것을 나타냅니다. 이 방법의 시간 복잡성은 O (n)이지만 공간은 실제로 ... 나는 그것에 대해 말하지 않을 것입니다 (*  ̄ ̄  ̄ ̄)
[생각 4] 먼저 확률을 계산하고 요구 사항을 충족시킬 가능성이 가장 높은 숫자의 수를 선택한 다음 몇 가지를 무작위로 선택하십시오. 이건 ... 잊어 버리세요.
[생각 5] 오늘의 주제는 소위 MJRTY 알고리즘으로, 다수의 투표 알고리즘이라고도합니다. 주요 아이디어는 다음과 같습니다. (이 알고리즘의 시간 복잡성은 O (N)입니다! 공간에 추가 저장이 필요하지 않으므로 공간 복잡성은 O (1) !!!)입니다.
count == 0이면 투표 값을 배열의 현재 요소로 설정하고 count를 1로 할당하십시오.
그렇지 않으면, 투표와 이제 배열 요소가 동일한 값, count ++, 그렇지 않으면 count;
배열이 스캔 될 때까지 위의 두 단계를 반복하십시오.
카운트는 0에 할당되고 처음부터 배열을 다시 스캔합니다. 배열 요소의 값이 투표 값과 동일하면 배열이 스캔 될 때까지 ++를 카운트하십시오.
이 시점에서 카운트 값이 N/2보다 크거나 동일하면 투표 가치가 반환됩니다. 그렇지 않으면 -1이 반환됩니다.
다음은 코드 구현입니다. 질문은 결과가 존재 해야하는지 확인하므로 확인 및 확인의 마지막 단계를 생략했습니다.
키 코드는 다음과 같습니다.
#include <iostream> 사용 네임 스페이스 std; int len; void find (int* a, int n) {char 후보; int ntimes, i; for (i = ntimes = 0; i <n; i ++) {if (ntimes == 0) 후보 = a [i], ntimes = 1; if (후보 == a [i]) ntimes ++; else ntimes-;}} cout embublate; } int main () {cin >> len; int a [len]; for (int i = 0; i <n; i ++) cin >> a [i]; find (a, len); System ( "pause"); return 0;}위는 편집자가 소개 한 발생 수의 절반 이상 (50%)입니다. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!