๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Algorithm/algorithm

์•Œ๊ณ ๋ฆฌ์ฆ˜ | ์ด๋ถ„ํƒ์ƒ‰ ๊ฐœ๋…๊ณผ ์˜ˆ์ œ + ์‹ฌํ™”

by ํžˆ์šค 2021. 8. 26.

๐Ÿ“Œ ๊ฐœ๋… ๋‹ค์ง€๊ธฐ

์ด๋ถ„ ํƒ์ƒ‰

ํƒ์ƒ‰ ๊ธฐ๋ฒ•์ค‘ ํ•˜๋‚˜๋กœ, ํƒ์ƒ‰ํ•˜๊ณ  ์‹ถ์€ ๋ฒ”์œ„๋ฅผ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋ถ„ํ• ํ•ด์„œ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๋‘ ๋ถ€๋ถ„์œผ๋กœ ๊ณ„์† ๋ถ„ํ• ํ•ด์„œ ์กฐ๊ฑด์— ๋งž๋Š”์ง€ ์ฐพ์•„๊ฐ€๊ธฐ ๋•Œ๋ฌธ์—, ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(log n)์œผ๋กœ ๋งค์šฐ ๋น ๋ฅธํŽธ์ด๋‹ค.

 

โœ”๏ธํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•

  1. ๋ฐฐ์—ด์ด ์ •๋ ฌ(sort)๋˜์–ด ์žˆ์–ด์•ผํ•œ๋‹ค.
  2. left์™€ right๋ฅผ ๋ฐฐ์—ด์˜ ์–‘ ๋์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.
  3. mid = (left + right) / 2 ๋กœ ์„ค์ •ํ•˜์—ฌ, mid ๊ฐ’์ด ๊ธฐ์ค€๊ฐ’๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ํฐ์ง€ ํ™•์ธํ•œ๋‹ค.
    1. (์˜ค๋ฆ„์ฐจ ๋ฐฐ์—ด ์ •๋ ฌ๋˜์–ด์žˆ์„ ๋•Œ) mid ๊ฐ’์ด ๊ธฐ์ค€๊ฐ’ ๋ณด๋‹ค ์ž‘๋‹ค๋ฉด, left๋ฅผ (mid+1)๋กœ ์„ค์ •ํ•œ๋‹ค. 
    2. (์˜ค๋ฆ„์ฐจ ๋ฐฐ์—ด ์ •๋ ฌ๋˜์–ด์žˆ์„ ๋•Œ) mid ๊ฐ’์ด ๊ธฐ์ค€๊ฐ’ ๋ณด๋‹ค ํฌ๋‹ค๋ฉด, right๋ฅผ (mid-1)๋กœ ์„ค์ •ํ•œ๋‹ค.
  4. left > right ๊ฐ€ ๋  ๋•Œ ๊นŒ์ง€ 2,3 ๋ฒˆ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

โœ๏ธ์ด๋ถ„ ํƒ์ƒ‰ ์˜ˆ์ œ1

์ž„์˜์˜ N๊ฐœ์˜ ์ˆซ์ž๊ฐ€ ์ž…๋ ฅ์œผ๋กœ ์ฃผ์–ด์กŒ์„ ๋•Œ, N๊ฐœ ์ˆ˜๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ๋‹ค์Œ N๊ฐœ์˜ ์ˆ˜ ์ค‘ ํ•œ ๊ฐœ์˜ ์ˆ˜์ธ M์ด ์ฃผ์–ด์ง„๋‹ค๋ฉด, 

์ด๋ถ„ ํƒ์ƒ‰์œผ๋กœ M์ด ์ •๋ ฌ๋œ ์ƒํƒœ์—์„œ ๋ช‡ ๋ฒˆ์งธ์— ์žˆ๋Š”์ง€ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•ด๋ผ. ์ค‘๋ณต๊ฐ’์€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

  • ์ž…๋ ฅ๊ฐ’ 
    • nums : N(3<=N<=1,000,000)๊ฐœ์˜ ์ˆ˜์—ด 
    • m : ์ˆซ์ž M
  • ์ถœ๋ ฅ๊ฐ’
    • ์ •๋ ฌํ•œ ๋’ค M์˜ ์ธ๋ฑ์Šค ๊ฐ’
  • ์ž…๋ ฅ ์˜ˆ์‹œ : [23, 87, 65, 12, 57, 32, 99, 81], 32
  • ์ถœ๋ ฅ ์˜ˆ์‹œ : 3
 function solution(nums, m) {
    let n = nums.length;
    // ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ
    nums.sort((a, b) => a - b); 

	// left, right๋กœ ๋ฐฐ์—ด์„ ํƒ์ƒ‰
    let lt = 0,
      rt = n - 1;
      
    // lt > rt์ผ ๋•Œ ํƒˆ์ถœ
    while (lt <= rt) { 
    // mid๊ฐ’ ์„ค์ •
      let mid = Math.floor((lt + rt) / 2);

	// m๊ณผ ๋น„๊ตํ•˜์—ฌ lt์™€ rt ๋ณ€๊ฒฝ. m๊ณผ ๋™์ผํ•˜๋ฉด ๊ทธ๋•Œ mid๊ฐ€ ์ •๋‹ต์ž„!
      if (nums[mid] < m) {
        lt = mid + 1;
      } else if (nums[mid] > m) {
        rt = mid - 1;
      } else {
        return mid;
      }
    }
 }
  console.log(solution([23, 87, 65, 12, 57, 32, 99, 81], 32)); // ์ •๋‹ต 2

 


๐Ÿ“Œ์‹ฌํ™” ํ•˜๊ธฐ

 

โœ๏ธ์ด๋ถ„ ํƒ์ƒ‰ ์˜ˆ์ œ2

์—˜๋ฆฌํŠธ ํ•™์›์€ ์ž์ฒด์ ์œผ๋กœ K๊ฐœ์˜ ๋žœ์„ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ K๊ฐœ์˜ ๋žœ์„ ์€ ๊ธธ์ด๊ฐ€ ์ œ๊ฐ๊ฐ์ด๋‹ค.

์„ ์ƒ๋‹˜์€ ๋žœ์„ ์„ ๋ชจ๋‘ N๊ฐœ์˜ ๊ฐ™์€ ๊ธธ์ด์˜ ๋žœ์„ ์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— K๊ฐœ์˜ ๋žœ์„ ์„ ์ž˜๋ผ์„œ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด 300cm ์งœ๋ฆฌ ๋žœ์„ ์—์„œ 140cm ์งœ๋ฆฌ ๋žœ์„ ์„ ๋‘ ๊ฐœ ์ž˜๋ผ๋‚ด๋ฉด 20cm ์€ ๋ฒ„๋ ค์•ผ ํ•œ๋‹ค. (์ด๋ฏธ ์ž๋ฅธ ๋žœ์„ ์€ ๋ถ™์ผ ์ˆ˜ ์—†๋‹ค.)

ํŽธ์˜๋ฅผ ์œ„ํ•ด ๋žœ์„ ์„ ์ž๋ฅผ๋•Œ ์†์‹ค๋˜๋Š” ๊ธธ์ด๋Š” ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉฐ, ๊ธฐ์กด์˜ K๊ฐœ์˜ ๋žœ์„ ์œผ๋กœ N๊ฐœ์˜ ๋žœ์„ ์„ ๋งŒ๋“ค ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋Š” ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

๊ทธ๋ฆฌ๊ณ  ์ž๋ฅผ ๋•Œ๋Š” ํ•ญ์ƒ ์„ผํ‹ฐ๋ฏธํ„ฐ ๋‹จ์œ„๋กœ ์ •์ˆ˜ ๊ธธ์ด๋งŒํผ ์ž๋ฅธ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

N๊ฐœ๋ณด๋‹ค ๋งŽ์ด ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ N๊ฐœ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์— ํฌํ•จ๋œ๋‹ค.

์ด๋•Œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ๋žœ์„ ์˜ ๊ธธ์ด๋ฅผ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

 

์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜ nums์— K๊ฐœ์˜ ๊ฐ ๋žœ์„ ์˜ ๊ธธ์ด๊ฐ€ ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค. ๊ฐ ๋žœ์„ ์˜ ๊ธธ์ด๋Š” 1,000,000 ์ดํ•˜์ด๋‹ค.
๋งค๊ฐœ๋ณ€์ˆ˜ n์— N์ด ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค.
K๋Š” 1์ด์ƒ 10,000์ดํ•˜์˜ ์ •์ˆ˜์ด๊ณ , N์€ 1์ด์ƒ 1,000,000์ดํ•˜์˜ ์ •์ˆ˜์ด๋‹ค.
๊ทธ๋ฆฌ๊ณ  ํ•ญ์ƒ K โ‰ฆ N ์ด๋‹ค.
[802, 743, 457, 539], 11
์ถœ๋ ฅ N๊ฐœ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋žœ์„ ์˜ ์ตœ๋Œ€ ๊ธธ์ด๋ฅผ ์„ผํ‹ฐ๋ฏธํ„ฐ ๋‹จ์œ„์˜ ์ •์ˆ˜๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. 200

 

โœ”๏ธ์ž…์ถœ๋ ฅ ๋ถ„์„

์ž…๋ ฅ์ด nums = [802, 743, 457, 539], n = 11 ์ผ ๋•Œ,

nums์— ๋“ค์–ด์žˆ๋Š” ๋žœ์„ ๋“ค์„ ๊ฐ€์ง€๊ณ  11๊ฐœ์˜ ๊ฐ™์€ ๊ธธ์ด์˜ ๋žœ์„ ์„ ๋งŒ๋“ค๋ ค๊ณ  ํ•  ๋•Œ, ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ๋žœ์„  ๊ธธ์ด๋ฅผ ๊ตฌํ•ด์•ผ ํ•œ๋‹ค.

์ตœ๋Œ€ ๋žœ์„ ์˜ ๊ธธ์ด๋Š” 200์œผ๋กœ, 

802 = 200 + 200 + 200 + 200 + 2

743 = 200 + 200 + 200 + 143

457 = 200 + 200 + 57

539 = 200 + 200 + 139

์ผ ๋•Œ, ๊ธธ์ด 200์˜ ๋žœ์„ ์ด 11๊ฐœ๋กœ n๊ฐ’์„ ๋งŒ์กฑํ•˜๋ฏ€๋กœ ์ •๋‹ต์ด๋‹ค. 

 

โœ”๏ธ๋ฌธ์ œ ๋ถ„์„

์ตœ๋Œ€ ๋žœ์„  ๊ธธ์ด๋Š” nums์— K๊ฐœ์˜ ๋žœ์„  ๊ธธ์ด๊ฐ€ ์ฃผ์–ด์งˆ ๋•Œ, ๊ฐ€์žฅ ๊ธด ๋žœ์„ ์˜ ๊ธธ์ด๋ฅผ ๋„˜์„ ์ˆ˜ ์—†๋‹ค.

์ฆ‰, ์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” 1 ~ 802 ์‚ฌ์ด์˜ ๊ฐ’์ด ์ž๋ฅผ ์ˆ˜ ์žˆ๋Š” ๋žœ์„  ๊ธธ์ด๊ฐ€ ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๊ทธ ์‚ฌ์ด์—์„œ ์ •๋‹ต์ด ๋‚˜์˜จ๋‹ค.

๋”ฐ๋ผ์„œ 1 ~ 802 ์‚ฌ์ด์˜ ๊ฐ’์„ ์ด๋ถ„ํƒ์ƒ‰์œผ๋กœ ๋Œ๋ฉด์„œ m ๊ฐ’์„ ๋งŒ์กฑ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค.

 

๊ทธ๋Ÿผ nums๋ฐฐ์—ด์— ์žˆ๋Š” ์ตœ๋Œ€๊ฐ’์„ ๊ผญ ์ฐพ์•„์•ผ ํ• ๊นŒ?

์•„๋‹ˆ๋‹ค. ๋žœ์„ ์˜ ๊ธธ์ด๋Š” 1,000,000์ด ์ตœ๋Œ€์ด๋ฏ€๋กœ, ์ตœ๋Œ€ ๋žœ์„  ๊ธธ์ด๋Š” 1 ~ 1,000,000 ์‚ฌ์ด์— ์กด์žฌํ•œ๋‹ค.

์ด๋ถ„ํƒ์ƒ‰์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(log n)์ด๋ฏ€๋กœ, log 1,000,000 == log 2^20 == 20 ๋ฒˆ๋งŒ ํƒ์ƒ‰ํ•˜๋ฉด ๋œ๋‹ค.

 

๋”ฐ๋ผ์„œ 20๋ฒˆ ํƒ์ƒ‰ํ•˜๋ฉด์„œ, mid๊ฐ’์œผ๋กœ m๊ฐœ์˜ ๋žœ์„ ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž˜ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

ํ’€์ด ์ฝ”๋“œ๋Š” ๋‹ค์Œ์„ ์ฐธ๊ณ ํ•˜์ž.

 

 

 // ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜
  function cntNum(x, nums) {
    let result = 0;

    // ๊ธธ์ด x๋กœ ๋žœ์„ ์„ ์ž˜๋ผ์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋žœ์„ ์˜ ๊ฐฏ์ˆ˜๋ฅผ ๊ตฌํ•จ
    for (let i of nums) {
      result += parseInt(i / x);
    }
    return result;
  }
  function solution(nums, n) {
    // ๋žœ์„ ์˜ ์ตœ๋Œ€๊ธธ์ด๊ฐ€ 1000000์ด๋ฏ€๋กœ, ๊ทธ ์‚ฌ์ด ์•ˆ์—์„œ ์ •๋‹ต์ด ๋‚˜์˜จ๋‹ค. => ์ด๋ถ„ํƒ์ƒ‰
    let lt = 0,
      rt = 1000000;
    let answer;

    while (lt <= rt) {
      let mid = Math.floor((lt + rt) / 2);
      let cnt = cntNum(mid, nums); // ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜.

      if (cnt >= n) {
        answer = mid;
        lt = mid + 1;
      } else if (cnt < n) {
        rt = mid - 1;
      }
    }
    return answer;
  }
  console.log(solution([802, 743, 457, 539], 11)); // 200