
๐ค ๋ฌธ์ : Maximum Frequency Stack | LeetCode 895
๋ฌธ์ : https://leetcode.com/problems/maximum-frequency-stack/
๋ฌธ์ ์์ ๋ง๋ค๊ณ ์ ํ๋ Frequncy Stack์
- ๊ธฐ์กด stack๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋ง
- pop ํ ๋ ๋จ์ํ ๊ฐ์ฅ ์์ ์๋ ์์๊ฐ ์๋
- ๊ฐ์ฅ ๋ง์ด ๋ค์ด์๋ ์์๋ค ์ค ๊ฐ์ฅ ์์ ์๋ ์์๋ฅผ ๋ฐํํจ
=> ๊ฐ ์์๊ฐ ๋ช ๋ฒ ๋์๋์ง๋ฅผ ํจ์จ์ ์ผ๋ก countํ๊ณ cachingํ ๋ฐฉ๋ฒ์ด ํ์ํจ
๐ก ํ์ด
1. Popํ ๋ Stack ๋ด ๋ชจ๋ ์์๋ฅผ ์ธ์ด ๊ฐ์ฅ ๋ง์ด ๋์จ ์์๋ฅผ ๋ฐํ
์ฒ์์๋ Time Limit Exceed ์ ๊ฒฝ์ฐ์ง ์๊ณ , ๊ฐ์ฅ ๋จ์ํ ํ์ด๋ก ํ์ด๋ด ๋๋ค.
- push ๋ ๊ธฐ์กด stack๊ณผ ๋์ผํ๊ณ
- pop ์ ์ ์ฒด stack์ ๋๋ฉฐ ๊ฐ ์์์ ๊ฐฏ์๋ฅผ countํ์ฌ ๊ฐ์ฅ ๋ง์ด ๋์จ ์์ ๋ฐํ
var FreqStack = function() {
this.array = []; // stack
};
/**
* push operation์ ๊ธฐ์กด Stack๊ณผ ๊ฐ์
*/
FreqStack.prototype.push = function(val) {
this.array.push(val)
};
/**
* pop operation์ ๋ฐํ ์ ์ ์ ์ฒด array๋ฅผ iterationํ๋ฉฐ ๊ฐ element๊ฐ ๋ช ๋ฒ ๋ฑ์ฅํ๋์ง count ํ ํ
* ๊ฐ์ฅ ๋ง์ด ๋์จ element์ ๊ฐ์ฅ ๋ง์ง๋ง์ ๋ค์ด์จ ์์น๋ฅผ pop
*/
FreqStack.prototype.pop = function() {
var max = 0; // ๊ฐ์ฅ ๋ง์ด ๋์จ element์ ๋น๋
var maxPosition = 0; // ๊ฐ์ฅ ๋ง์ด ๋์จ element์ ๋ง์ง๋ง position
const cache = [];
for(const index in this.array){
const i = this.array[index];
// i๊ฐ ๋ช ๋ฒ ๋์๋์ง count
if(!cache[i])
cache[i] = 1;
else cache[i]++;
// ๊ฐ์ฅ ๋ง์ด ๋์จ ๋น๋๋ณด๋ค ํด ๊ฒฝ์ฐ max๊ฐ update
if(cache[i] >= max){
max = cache[i];
maxPosition = index;
}
}
const result = this.array[maxPosition];
this.array.splice(maxPosition, 1);
return result;
};
Time Complexity
push : O1 stack์ ๊ฐ์ฅ top์ push
pop :ON stack ์ ์ฒด๋ฅผ ๋๋ฉฐ ๊ฐ ์์์ ๋น๋๋ฅผ count
Space Complexity
ON ๊ฐ ์์๋ฅผ ํ๋ฒ์ฉ๋ง ์ ์ฅํ๋ฉด ๋จ
์ ๋ต์ ์ํ๋๋๋ก ๋์ค์ง๋ง ์ญ์๋.. TLE ์
๋๋ค.
pop operation์ ON๋ณด๋ค ๋น ๋ฅด๊ฒ ํ ๋ฐฉ๋ฒ์ด ํ์ํด ๋ณด์ด๋ค์.

2. Double Stack ๊ตฌ์กฐ๋ก ๊ฐ ์์์ ๋น๋ caching
๊ฐ ์์๊ฐ ๋ช๋ฒ ๋์๋์ง๋ฅผ ๋งค๋ฒ countํ์ง ์์๋ ๋๋๋ก
ํจ์จ์ ์ผ๋ก ์ ์ฅํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ ์ฌ๋ ค์ผ ํ๋๋ฐ์,
์ ๊ฐ ๊ณ ๋ฏผํ ํํ๋ ์๋์ ๊ฐ์ ์ด์ค stack์
๋๋ค.
stack์ด ์ธต ๋ณ๋ก ๋์์ง ํํ์ธ๋ฐ, ๊ฐ N์ธต์ stack์ N๋ฒ์งธ๋ก ๋ค์ด์จ ์์๋ค๋ผ๋ฆฌ์ stack์ด๋ผ๊ณ ๋ณด๋ฉด ๋ฉ๋๋ค.
ํด๋น์์์๋น๋์ํด๋นํ๋์ธต์push

์๋ฅผ๋ค์ด 5 7 5 7 4 5 ์์ผ๋ก ๊ฐ์ด ๋ค์ด์จ๋ค๋ฉด, ์๋ ์์๋ก stack์ ๋ชจ์ต์ด ๊ทธ๋ ค์ง๋๋ค.

์ด๋ ๊ฒ ๋๋ฉด ๊ฐ์ฅ ๋์์ธต์๋ ์ง๊ธ๊น์ง ์ค ๊ฐ์ฅ ๋น๋๊ฐ ๋์ ์ซ์๋ค์ด ๋ค์ด๊ฐ ์์ผ๋ฉฐ,
๊ฐ ์ธต์์๋ ๊ฐ์ฅ ๋ง์ง๋ง์ ๋ค์ด์จ ์ซ์๋ stack์ top์ ์๋ ๊ตฌ์กฐ๋ก ์ ์ง๋ฉ๋๋ค.
๋ฐ๋ผ์ pop์ ํ ๋๋ ๊ฐ์ฅ ๋์์ธต์ stack์์ ํ๋์ฉ Pop์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
var FreqStack = function() {
this.doubleStack = []; // ์ด๋ค ์ซ์๊ฐ ๋ช ๋ฒ์งธ์ ๋์๋์ง
/** ex)
* [, [1, 2, 5], [2, 1], [1]] => 1์ 3๋ฒ 2๋ 2๋ฒ 5๋ 1๋ฒ ๋์ด
**/
};
/**
* @param {number} val
* @return {void}
*/
FreqStack.prototype.push = function(val) {
for(var i=this.cache.length; i>0; i--){ // ๊ฐ์ฅ ์์ธต๋ถํฐ ๋๋ฉด์
if(this.cache[i] && this.cache[i].includes(val)){ // ๊ทธ ์ธต์ val์ด ์์ผ๋ฉด
if(this.cache[i+1]) this.cache[i+1].push(val) // ๊ทธ ์์ธต์ val์ push
else this.cache[i+1] = [val]
return;
}
}
if(this.cache[1]) this.cache[1].push(val) // ๋ชจ๋ ์ธต์ val์ด ์์ผ๋ฉด 1์ธต์ push
else this.doubleStack[1] = [val]
return;
};
/**
* @return {number}
*/
FreqStack.prototype.pop = function() {
const maxFrequency = this.doubleStack.length-1;
const targetNum = this.doubleStack[maxFrequency].pop();
if(this.doubleStack[maxFrequency].length === 0) this.doubleStack.pop();
return targetNum;
};
Time Complexity
push : ON ์ ์ฒด stack์ ๋๋ฉฐ ํด๋น ์์๋ฅผ ์ฐพ์์ผ ํจ
pop :O1 stack์ ๊ฐ์ฅ ์์ ์์๋ฅผ pop
Space Complexity
ON ๊ฐ ์์๋ฅผ ํ๋ฒ์ฉ๋ง ์ ์ฅํ๋ฉด ๋จ
์ ์ถํ๋ ํต๊ณผ๋ ๋์๋๋ฐ์,
์๊ฐํด๋ณด๋ฉด pushํ ๋ stack์ iterationํ๋ฉฐ ๋ช๋ฒ์งธ ์ธต์ ๋์จ์ ์ด ์๋์ง ํ์ธํด์ผ ํ๋ push operation์ TC๋ ์ฌ์ ํ ON์ด ๋๊ฒ ๋ค์.
๊ฐ์ ์์๊ฐ ์ฌ๋ฌ๋ฒ ๋ฐ๋ณตํด์ ๋ค์ด์จ๋ค๋ฉด ์ด ๋ฐฉ๋ฒ์ด ํจ์จ์ ์ด๊ฒ ์ง๋ง, ์๋ก์ด ์์๊ฐ ๊ณ์ ๋ค์ด์จ๋ค ์๊ฐํ๋ฉด Stack ์ ์ฒด๋ฅผ iterationํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์ง๋ฏ๋ก 1๋ฒ ํ์ด์ ๋น์ทํ ์๋๊ฐ ๋ ์๋ ์๊ฒ ์ต๋๋ค.
ํต๊ณผ๋ ๊ฒ์ ๋ณด๋ฉด ํ ์คํธ์ผ์ด์ค์
- ๊ฐ์ ์์๋ฅผ ์ฌ๋ฌ๋ฒ pushํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ณ
- Stack์ด ์์ฃผ ํด ๋ pop์ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์
push๋ณด๋ค๋ pop์ ํจ์จ์ฑ์ด ์ค์ํ์ง ์์๋ ์๊ฐ์ด ๋ญ๋๋ค.

3. 2๋ฒํ์ด push์ TCTimeComplexity์ต์ ํ
2๋ฒ ํ์ด์ Push operation์ ์ข ๋ ์ต์ ํํด๋ณด๊ฒ ์ต๋๋ค.
Stack์ ๋๋ฉฐ ๋ช์ธต์ pushํ ์ง ์ ํ๋๊ฒ ์๋๋ผ, inFloor๋ผ๋ ์ด๋ฆ์ cache๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ๊น์ง์ ๋น๋๋ฅผ ๋ฐ๋ก ์ ์ฅํด๋๊ฒ ์ต๋๋ค.
pushํ ๋๋ inFloor[val]+1 ์ธต์ pushํ๋ฉด ๋๊ฒ ์ง์
var FreqStack = function() {
this.doubleStack = []; // ์ด๋ค ์ซ์๊ฐ ๋ช ๋ฒ์งธ์ ๋์๋์ง
/** ex)
* [, [1, 2, 5], [2, 1], [1]] => 1์ 3๋ฒ 2๋ 2๋ฒ 5๋ 1๋ฒ ๋์ด
**/
this.inFloor = []; // ๊ฐ element์ ๋น๋
/** ex)
* [, 3, 2, , , 1] => 1์ 3๋ฒ 2๋ 2๋ฒ 5๋ 1๋ฒ ๋์ด
**/
};
FreqStack.prototype.push = function(val) {
if(!this.inFloor[val]) this.inFloor[val] = 0;
this.inFloor[val]++;
if(!this.doubleStack[this.inFloor[val]]) this.doubleStack[this.inFloor[val]] = []
this.doubleStack[this.inFloor[val]].push(val)
};
FreqStack.prototype.pop = function() {
const maxFrequency = this.doubleStack.length-1;
const targetNum = this.doubleStack[maxFrequency].pop();
this.inFloor[targetNum]--;
if(this.doubleStack[maxFrequency].length === 0) this.doubleStack.pop();
return targetNum;
};
Time Complexity
push : O1 ์ ์ฒด stack์ ๋๋ฉฐ ํด๋น ์์๋ฅผ ์ฐพ์์ผ ํจ
pop :O1 stack์ ๊ฐ์ฅ ์์ ์์๋ฅผ pop
Space Complexity
ON ๊ฐ ์์๋ฅผ ํ๋ฒ์ฉ๋ง ์ ์ฅํ๋ฉด ๋จ

๐ Learned
js๋ก ํธ๋ ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ์ค ์ด๋ ๊ฒ ํด๋์ค๋ฅผ ๊ตฌํํด๋ด์ผ ํ๋ ๋ฌธ์ ๋ ์์ํด์, push์ popํจ์๋ฅผ ์ด๋์ ์์ฑํด์ผํ๋์ง, ํด๋์ค ๋ด์ ๋ณ์๋ ์ด๋ป๊ฒ ์ ์ธํด์ผ ํ๊ณ , ํจ์ ๋ด์์ ๊ทธ ๋ณ์๋ฅผ ์ด๋ป๊ฒ ์ ๊ทผํด์ผ ํ๋์ง ์ข ํค๋งธ์ต๋๋ค..;;
์์ ํ์ด์ฒ๋ผ .prototype.ํจ์ ๋ก ์์ฑํด๋ ๋๊ณ
์๋ ์ฒ๋ผ๋ ๊ตฌํ ๊ฐ๋ฅํฉ๋๋ค
function FreqStack() { let m =[]; return { push, pop } function push(x) { m.push(x) ... } function pop() { m.pop(x) ... } }