[JS]プログラマーの宝石購入
22591 ワード
質問リンク
https://programmers.co.kr/learn/courses/30/lessons/67258
中学3年生
まず無知な...
最初のインデックスから,満たされた区間内で最短区間を求める.
2中for Moonなので、タイムアウトは間違いないと知っていましたが...むなしい
function solution(gems) {
var answer = [];
const db = new Set(gems);
if (db.size === 1) return [1, 1]
gems.forEach((gem, idx) => {
const visit = {};
[...db].forEach(el => visit[el] = 1);
visit[gem] = 0;
var targetLen = db.size - 1, nextIdx = idx;
for (; nextIdx < gems.length; nextIdx++) {
const target = gems[nextIdx];
if (visit[target]) {
targetLen--;
if (targetLen === 0) break;
visit[target] = 0;
}
}
if (!targetLen) answer.push([idx + 1, nextIdx + 1]);
})
return answer.reduce((ac, v) =>
ac[1] - ac[0] > v[1] - v[0] ? v : ac, [1, gems.length]);
}
再解釈
スライドウィンドウアルゴリズム
理論上O(n)
ウィンドウを順次拡張します.
AA BB BB AA AA CC DD AA
AA: 1, BB: 2
繰り返しが発生すると、インデックスが加算されます.
AA BB BB AA AA CC DD AA
AA: 1, BB: 3
条件が満たされたら正解候補に変更する->正解と比較する
AA BB BB AA AA CC DD AA
AA: 5, BB: 3, CC: 6, DD: 7 -> [3, 7]
AA BB BB AA AA CC DD AA
AA: 8, BB: 3, CC: 6, DD: 7 -> [3, 8]
function solution(gems) {
const cnt = new Set(gems).size;
const gemMap = {};
var answer = [1, gems.length];
gems.forEach((gem, i) => {
gemMap[gem] = i;
const target = Object.values(gemMap);
if (target.length === cnt) {
const cand = [Math.min(...target) + 1, i + 1];
answer = answer[1] - answer[0] > cand[1] - cand[0] ? cand : answer;
}
})
return answer;
}
演算子を展開...和Math.min
,Object.values
で配列長を求める過程は想像以上に重いようだ.最終コード
他の人と同じように...Mapオブジェクトを使用すると簡単にsizeを取得できます.
Mapは挿入順序を保持し,最小比較演算は不要である.
function solution(gems) {
const cnt = new Set(gems).size;
const gemMap = new Map();
var answer = [1, gems.length];
gems.forEach((gem, i) => {
gemMap.delete(gem);
gemMap.set(gem, i);
if (gemMap.size === cnt){
const cand = [gemMap.values().next().value + 1, i + 1];
answer = answer[1] - answer[0] > cand[1] - cand[0] ? cand : answer;
}
})
return answer;
}
私たちはMap.を使います.
コードの追加
公式の問題を参考にして説明し,書き直す
https://tech.kakao.com/2020/07/01/2020-internship-test/
これはより直感的なアルゴリズムのようだ.
function solution(gems) {
const cnt = new Set(gems).size;
var ans = [1, gems.length];
var l = 0, r = 0;
const hit = new Map();
hit.set(gems[0], 1)
while (r < gems.length) {
if (hit.size === cnt) {
if(ans[1] - ans[0] > r - l)
ans = [l + 1, r + 1]
hit.set(gems[l], hit.get(gems[l]) - 1);
if (hit.get(gems[l]) === 0)
hit.delete(gems[l])
l++;
}
else {
r++;
const right = hit.get(gems[r]);
hit.set(gems[r], right ? right + 1 : 1);
}
}
return ans;
}
Reference
この問題について([JS]プログラマーの宝石購入), 我々は、より多くの情報をここで見つけました https://velog.io/@bepyan/JS-프로그래머스-보석-쇼핑テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol