관리 메뉴

Partially Committed

[Algorithm] Non-Constructible Value λ³Έλ¬Έ

πŸ”₯ Algorithm || λ¬Έμ œν’€μ΄/PS

[Algorithm] Non-Constructible Value

WonderJay 2022. 10. 25. 17:14
728x90
λ°˜μ‘ν˜•
SMALL

  였늘 λ‹€λ£° μ£Όμ œλŠ” Non-Constructible Value(Change) 이닀. positive integer 둜 κ΅¬μ„±λœ array κ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, 각각의 μ›μ†Œλ“€μ˜ ν•©μœΌλ‘œ λ‚˜νƒ€λ‚Ό 수 μ—†λŠ” μ΅œμ†Œμ˜ 값을 Non-Constructible Value 라고 μ •μ˜ν•œλ‹€. 예λ₯Ό λ“€μ–΄, coins 배열이 [1, 2, 5] 둜 μ£Όμ–΄μ‘Œμ„ λ•Œ 각각의 μ›μ†Œλ“€λ‘œ λ§Œλ“€μ–΄λ‚Ό 수 μžˆλŠ” 값은 1, 2, 3, 5 μ΄λ―€λ‘œ Non-Constructible Value λŠ” 4 이닀. 

 

  κ°€μž₯ λ¨Όμ € λ– μ˜¬λ¦΄ 수 μžˆλŠ” 방법은 μ£Όμ–΄μ§„λŒ€λ‘œ 꾸덕꾸덕 κ΅¬ν˜„ν•˜λŠ” 것이닀. 주어진 배열을 ascending order 으둜 sorting ν•œ λ‹€μŒμ— λͺ¨λ“  μ›μ†Œλ“€μ˜ 합을 κ΅¬ν•œλ‹€. 그러면 Non-Constructive Value λŠ” 1~max_sum+1 쀑 ν•˜λ‚˜μΌ 것이 자λͺ…ν•˜λ‹€. Non-Constructible Value 인지 μ•„λ‹Œμ§€λ₯Ό 1λΆ€ν„° μ°¨κ·Όμ°¨κ·Ό κ²€μ‚¬ν•΄λ‚˜κ°€λ©΄ λœλ‹€. 이λ₯Ό μœ„ν•œ λ³€μˆ˜λ₯Ό current_sum 이라고 ν•˜μž. κ²€μ‚¬ν•œλ‹€λŠ” 것은 주어진 배열을 1회 μˆœνšŒν•˜λ©΄μ„œ, λ°°μ—΄ λ‚΄ μ›μ†Œλ“€λ‘œ current_sum 을 λ§Œλ“€μ–΄λ‚Ό 수 μžˆλŠ”μ§€ μ•„λ‹Œμ§€λ₯Ό μ²΄ν¬ν•œλ‹€λŠ” 것이닀. κ΅¬ν˜„ν•˜κΈ° 전에 μ‹œκ°„ λ³΅μž‘λ„λ₯Ό κ°„λ‹¨ν•˜κ²Œ 계산해보아야 ν•œλ‹€. outer loop μ—μ„œ current_sum 을 1 λΆ€ν„° max_sum κΉŒμ§€ μ¦κ°€μ‹œν‚¬ 것이고 inner loop μ—μ„œλŠ” given array λ₯Ό μˆœνšŒν•˜λ©΄μ„œ Constructible ν•œμ§€ μ•„λ‹Œμ§€ νŒλ‹¨ν•˜λ―€λ‘œ O(N*M) 의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό 가지며 곡간 λ³΅μž‘λ„λŠ” O(1) μž„μ„ μ•Œ 수 μžˆλ‹€. μ΄λ•Œ N 은 given array 의 size 이고 M 은 max_sum 이닀.

 

  current_sum 이 Constructible ν•œμ§€ μ•„λ‹Œμ§€λ₯Ό νŒλ‹¨ν•˜λŠ” 과정을 쑰금 더 μžμ„Έν•˜κ²Œ μ„€λͺ…해보겠닀. current_sum 보닀 μž‘κ±°λ‚˜ 같은 μ›μ†Œλ₯Ό λ§ˆμ£Όν•˜λ©΄, current_sum μ—μ„œ ν•΄λ‹Ή μ›μ†Œμ˜ 값을 λΊ€λ‹€. 이λ₯Ό λͺ¨λ“  μ›μ†Œλ“€μ— λŒ€ν•΄μ„œ λ°˜λ³΅ν•˜λ©΄, current_sum 이 0μ΄κ±°λ‚˜ 0 보닀 클 것이닀. current_sum 이 0이 λ˜μ—ˆλ‹€λŠ” 것은 ν•΄λ‹Ή current_sum 은 Constructible ν•˜λ―€λ‘œ inner loop λ₯Ό νƒˆμΆœν•œλ‹€. current_sum 이 0보닀 ν¬λ‹€λŠ” 것은, current_sum 이 Non-Constructible ν•˜λ‹€λŠ” 것이닀. μ™œλƒλ©΄ array λ‚΄μ˜ μ›μ†Œλ“€μ˜ ν•©μœΌλ‘œ current_sum 을 λ‚˜νƒ€λ‚Ό 수 μ—†κΈ° λ•Œλ¬Έμ΄λ‹€. κ·ΈλŸ¬λ―€λ‘œ current_sum > 0 이면, current_sum 을 λ°˜ν™˜ν•˜λ©΄ λ˜λŠ”λ° μ£Όμ˜ν•  점은 current_sum 이 constructible ν•œμ§€ μ•„λ‹Œμ§€ νŒλ‹¨ν•˜λŠ” κ³Όμ •μ—μ„œ current_sum μ—μ„œ array 의 μ›μ†Œλ₯Ό subtract ν–ˆμœΌλ―€λ‘œ, current_sum 에 ν•΄λ‹Ήν•˜λŠ” outer index λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€λŠ” 것이닀.  λ§Œμ•½ inner loop, outer loop λ₯Ό λͺ¨λ‘ νƒˆμΆœν•˜κ²Œ 되면 max_sum μ΄ν•˜λ‘œ Non-constructible Value κ°€ μ—†λ‹€λŠ” κ²ƒμ΄λ―€λ‘œ max_sum+1 이 Non-constructible Value κ°€ λœλ‹€. 이λ₯Ό μ½”λ“œλ‘œ μž‘μ„±ν•˜λ©΄ μ•„λž˜μ™€ κ°™λ‹€.

#include <vector>
using namespace std;
// brute - force 
// time  : O(NM) -> N is # of coins , M is max_sum
// space : O(1)
int nonConstructibleChange(vector<int> coins) {
	// Write your code here.
	int max_sum = 0;
	int current_coin = 0;
	int current_sum = 0;
	sort(coins.begin(), coins.end());
	for (auto ele : coins) {
		max_sum += ele;
	}
	for (int i = 1; i < max_sum; i++) {
		current_sum = i;
		for (int j = coins.size() - 1; j >= 0; j--) {
			current_coin = coins[j];
			if (current_coin <= current_sum) {
				current_sum -= current_coin;
			}
			if (current_sum == 0) {
				break;
			}
		}
		if (current_sum > 0) {
          return i;
		}
	}
	return max_sum+1;
}

  μœ„ 방법을 optimize ν•œ ν•˜λ‚˜μ˜ loop 만으둜 ν•΄κ²°ν•˜λŠ” clever ν•œ 풀이가 μ‘΄μž¬ν•œλ‹€. μ‹œμž‘μ€ λ™μΌν•˜λ‹€. 주어진 array λ₯Ό ascending order 둜 sorting ν•œ λ‹€μŒμ—, current_sum 을 0으둜 μ΄ˆκΈ°ν™” ν•œλ‹€.

 

  주어진 array κ°€ [1,2,5] 라면 ν•΄λ‹Ή array λ₯Ό μ •λ°©ν–₯으둜 μˆœνšŒν•˜λ©΄μ„œ array[i] 와 current_sum+1 을 λΉ„κ΅ν•œλ‹€. λ§Œμ•½ array[i] > current_sum+1 이면 current_sum+1 은 Non-Constructible ν•˜λ‹€. μ²˜μŒμ—λŠ” array[0] = 1 κ³Ό current_sum+1 = 1 을 비ꡐ할 것이고, μ—¬κΈ°μ„œλŠ” array[0] == current_sum+1 이기 λ•Œλ¬Έμ— current_sum+1 이 Non-Construtible ν•˜μ§€λŠ” μ•ŠμœΌλ―€λ‘œ current_sum 에 array[0] 을 더해쀀닀. 그러면 λ‹€μŒ λ°˜λ³΅μ—μ„œλŠ” array[1] = 2 이고, current_sum+1 = 2 인데 array[1] == current_sum+1 μ΄λ―€λ‘œ current_sum+1 이 Non-Constructible ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ array[1] 을 더해쀀닀. λ‹€μŒμ€ array[2] = 5 이고, current_sum+1 이 4 κ°€ 되고 array[2] > current_sum+1 μ΄λ―€λ‘œ current_sum+1 을 array λ‚΄μ˜ μ›μ†Œλ“€μ˜ ν•©μœΌλ‘œ λ‚˜νƒ€λ‚Ό 수 μ—†κ²Œ λœλ‹€. κ·ΈλŸ¬λ―€λ‘œ current_sum+1 을 λ°˜ν™˜ν•΄μ£Όλ©΄ λœλ‹€. ν•΄λ‹Ή ν’€μ΄λŠ” μ΄ˆκΈ°μ— 정렬을 ν•΄μ•Όν•˜λ―€λ‘œ μ‹œκ°„ λ³΅μž‘λ„ O(nlogn) 이며 곡간 λ³΅μž‘λ„λŠ” O(1) 이닀. μ½”λ“œλŠ” μ•„λž˜μ™€ κ°™λ‹€.

#include <vector>
using namespace std;

// solution2.cpp
// time  :  O(nlogn)
// space :  O(1)

int nonConstructibleChange(vector<int> coins) {
	// Write your code here.
	sort(coins.begin(), coins.end());
	int current_sum = 0;
	for (int i = 0; i < coins.size(); i++) {
		if (coins[i] > current_sum + 1)
			return current_sum + 1;
		current_sum += coins[i];
	}
	return current_sum + 1;
}

  μ‹€μ œ λ©΄μ ‘μž₯μ΄λ‚˜ μ½”λ”©ν…ŒμŠ€νŠΈλ₯Ό λ³Ό λ•Œ, 이와 같이 효율적인 방법이 λ°”λ‘œ λ– μ˜€λ₯΄μ§€ μ•Šμ„ κ°€λŠ₯성이 클 것 κ°™λ‹€. 면접이라면 brute - force 방식을 λ¨Όμ € κ΅¬ν˜„ν•˜λ©΄μ„œ clever ν•œ ν’€μ΄λ‘œ κ°€λŠ” 아이디어λ₯Ό 면접관을 톡해 μ–»μ–΄λ‚΄μ„œ κ΅¬ν˜„ν•˜λ©΄ 될 것 κ°™κ³ , μ½”λ”© ν…ŒμŠ€νŠΈλΌλ©΄ constraint λ₯Ό 잘 νŒŒμ•…ν•˜κ³  brute-force 둜 TLE κ°€ λ°œμƒν•˜μ§€ μ•Šμ„κ²ƒ κ°™μœΌλ©΄ κ³ λ―Όν•˜μ§€λ§κ³  λ°”λ‘œ κ΅¬ν˜„ν•΄μ„œ ν†΅κ³Όν•˜λŠ” 것이 쒋을 것 κ°™λ‹€.

https://github.com/versatile0010/AlgoExpert

 

GitHub - versatile0010/AlgoExpert: Solutions to AlgoExpert Problems.

Solutions to AlgoExpert Problems. Contribute to versatile0010/AlgoExpert development by creating an account on GitHub.

github.com

 

728x90
λ°˜μ‘ν˜•
LIST
Comments