๐ํ๋ฒ๊ฑฐ ๋ง๋ค๊ธฐ
https://school.programmers.co.kr/learn/courses/30/lessons/133502
โ๏ธ๋ฌธ์ ์ค๋ช
ํ๋ฒ๊ฑฐ ๊ฐ๊ฒ์์ ์ผ์ ํ๋ ์์๋ ํ๋ฒ๊ฑฐ๋ฅผ ํฌ์ฅํ๋ ์ผ์ ํฉ๋๋ค. ํจ๊ป ์ผ์ ํ๋ ๋ค๋ฅธ ์ง์๋ค์ด ํ๋ฒ๊ฑฐ์ ๋ค์ด๊ฐ ์ฌ๋ฃ๋ฅผ ์กฐ๋ฆฌํด ์ฃผ๋ฉด ์กฐ๋ฆฌ๋ ์์๋๋ก ์์์ ์์ ์๋์๋ถํฐ ์๋ก ์์ด๊ฒ ๋๊ณ , ์์๋ ์์์ ๋ง๊ฒ ์์ฌ์ ์์ฑ๋ ํ๋ฒ๊ฑฐ๋ฅผ ๋ฐ๋ก ์ฎ๊ฒจ ํฌ์ฅ์ ํ๊ฒ ๋ฉ๋๋ค. ์์๊ฐ ์ผํ๋ ๊ฐ๊ฒ๋ ์ ํด์ง ์์(์๋์๋ถํฐ, ๋นต – ์ผ์ฑ – ๊ณ ๊ธฐ - ๋นต)๋ก ์์ธ ํ๋ฒ๊ฑฐ๋ง ํฌ์ฅ์ ํฉ๋๋ค. ์์๋ ์์ด ๊ต์ฅํ ๋น ๋ฅด๊ธฐ ๋๋ฌธ์ ์์๊ฐ ํฌ์ฅํ๋ ๋์ ์ ์ฌ๋ฃ๊ฐ ์ถ๊ฐ์ ์ผ๋ก ๋ค์ด์ค๋ ์ผ์ ์์ผ๋ฉฐ, ์ฌ๋ฃ์ ๋์ด๋ ๋ฌด์ํ์ฌ ์ฌ๋ฃ๊ฐ ๋์ด ์์ฌ์ ์ผ์ด ํ๋ค์ด์ง๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์์์ ์์ ์์ด๋ ์ฌ๋ฃ์ ์์๊ฐ [์ผ์ฑ, ๋นต, ๋นต, ์ผ์ฑ, ๊ณ ๊ธฐ, ๋นต, ์ผ์ฑ, ๊ณ ๊ธฐ, ๋นต]์ผ ๋, ์์๋ ์ฌ์ฏ ๋ฒ์งธ ์ฌ๋ฃ๊ฐ ์์์ ๋, ์ธ ๋ฒ์งธ ์ฌ๋ฃ๋ถํฐ ์ฌ์ฏ ๋ฒ์งธ ์ฌ๋ฃ๋ฅผ ์ด์ฉํ์ฌ ํ๋ฒ๊ฑฐ๋ฅผ ํฌ์ฅํ๊ณ , ์ํ ๋ฒ์งธ ์ฌ๋ฃ๊ฐ ์์์ ๋, ๋ ๋ฒ์งธ ์ฌ๋ฃ์ ์ผ๊ณฑ ๋ฒ์งธ ์ฌ๋ฃ๋ถํฐ ์ํ ๋ฒ์งธ ์ฌ๋ฃ๋ฅผ ์ด์ฉํ์ฌ ํ๋ฒ๊ฑฐ๋ฅผ ํฌ์ฅํฉ๋๋ค. ์ฆ, 2๊ฐ์ ํ๋ฒ๊ฑฐ๋ฅผ ํฌ์ฅํ๊ฒ ๋ฉ๋๋ค.
์์์๊ฒ ์ ํด์ง๋ ์ฌ๋ฃ์ ์ ๋ณด๋ฅผ ๋ํ๋ด๋ ์ ์ ๋ฐฐ์ด ingredient๊ฐ ์ฃผ์ด์ก์ ๋, ์์๊ฐ ํฌ์ฅํ๋ ํ๋ฒ๊ฑฐ์ ๊ฐ์๋ฅผ return ํ๋๋ก solution ํจ์๋ฅผ ์์ฑํ์์ค.
โ๏ธ์ ํ์ฌํญ
1 ≤ ingredient์ ๊ธธ์ด ≤ 1,000,000
ingredient์ ์์๋ 1, 2, 3 ์ค ํ๋์ ๊ฐ์ด๋ฉฐ, ์์๋๋ก ๋นต, ์ผ์ฑ, ๊ณ ๊ธฐ๋ฅผ ์๋ฏธํฉ๋๋ค.
โ๏ธ์ ์ถ๋ ฅ ์
ingredien | result |
[2, 1, 1, 2, 3, 1, 2, 3, 1] | 2 |
[1, 3, 2, 1, 2, 1, 3, 1, 2] | 0 |
โ๏ธ์ ์ถ๋ ฅ ์ ์ค๋ช
- ์
์ถ๋ ฅ ์ #1
๋ฌธ์ ์์์ ๊ฐ์ต๋๋ค.
- ์
์ถ๋ ฅ ์ #2
์์๊ฐ ํฌ์ฅํ ์ ์๋ ํ๋ฒ๊ฑฐ๊ฐ ์์ต๋๋ค.
๐ํ์ด ๋ฐ ๋ฆฌ๋ง์ธ๋ฉ(์คํฌ์ฃผ์)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class LS_133502 {
public int solution(int[] ingredient) {
int answer = 0;
StringBuilder sb = new StringBuilder();
for (int j : ingredient) {
sb.append(j);
if (sb.length() > 3 && sb.subSequence(sb.length() - 4, sb.length()).equals("1231")) {
answer++;
sb.delete(sb.length() - 4, sb.length());
}
}
return answer;
}
public int solution2(int[] ingredient) {
int answer = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ingredient.length; i++) {
sb.append(ingredient[i]);
}
String str = sb.toString();
while(str.contains("1231")){
str = str.replaceFirst("1231","");
answer++;
}
return answer;
}
}
|
cs |
์์ solution() ์ ๋ง์ ํ์ด solution2()์ ํ๋ฆฐ ํ์ด์ด๋ค.
โํ๋ฆฐ ํ์ด ๊ฒฐ๊ณผ
โญ๋ง์ ํ์ด ๊ฒฐ๊ณผ
ํ๋ฆฐ ํ์ด์ ๋ง์ ํ์ด์ ์๊ฐ ์ฐจ์ด๋ฅผ ๋ณด๋ฉด ์๋์ ์ธ ์๊ฐ ์ฐจ์ด๊ฐ ์๋ค๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
๐ํด์ค
๋ฌธ์ ๋ฅผ ๋ณด์๋ง์ ๋ฐฐ์ด์ ๋ฌธ์์ด๋ก ๋ฐ๊ฟ์ subString ์ด ์๋์ง ํ์ธํ๋ฉด ๋ ๊ฑฐ๋ผ ์๊ฐํ๋ค.
์ด๋ String ๊ทธ์์ฒด๋ฅผ ๋ค๋ฃจ๋ ๊ฒ ์๋๋ผ StringBuilder ๋ก์ ๋ค๋ค์ผํ๋๋ฐ, ์ด ์ฌ์ค์ ์๊ณ ๋ฌธ์ ๋ฅผ ํ์์ง๋ง ๋ง์ ์ฌ๋๋ค์ด ์ ๋ชจ๋ฅด๋ ๊ฑฐ ๊ฐ์ ๊ธ๋ ์ธ๊ฒธ ๋ฆฌ๋ง์ธ๋ฉํ ๊ฒธ ์์ฑํด ๋ณด์๋ค.
๋ง์ด๋ค ํธ๋ ๋ฐฉ๋ฒ์ด
[2, 1, 1, 2, 3, 1, 2, 3, 1] ์ ๋ฐฐ์ด์ด ์ฃผ์ด ์ง๋ค๋ฉด "211231231" ๋ก ๋ฌธ์์ด์ ๋ง๋ค๊ณ ์ด์ด์ง "1231"์ ๊ณต๋ฐฑ์ผ๋ก replace ์์ผ ๊ทธ ํ์๋ฅผ ์นด์ดํธ ํ๋ ๋ฐฉ๋ฒ์ ๋ ์ฌ๋ ธ์ ๊ฒ์ด๋ค.
๋ฐฉ๋ฒ๋ก ์ ์ผ๋ก ๋ง์ง๋ง String ์ผ๋ก ๋ก์ง์ ๋ค๋ฃฌ๋ค๋ฉด ์๊ฐ ์ด๊ณผ๊ฐ ๋ ๊ฒ์ด๋ค.
์ฐ๋ฆฌ๋ String ํด๋์ค์ ํน์ง์ ์์์ผํ๋ค.
ํนํ๋ String ์์ += ๋๋ + ์ฐ์ฐ์ ์ง์ ํด์ผํ๋ค.
String str = "1";
str += "2";
str += "3";
str += "4";
์ ์ ๊ฐ์ด ์ฐ์ฐ์ ํ๋ค๋ฉด ํ ๋ฌธ์์ด์ 1234 ๊ฐ ํฉ์ณ์ง ๋ฌธ์์ด์ด ๋๋๊ฒ ์๋๋ผ + ์ฐ์ฐ ํ ๋๋ง๋ค ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฐ์ฐ์ ์ํํ๊ธฐ ๋๋ฌธ์ด๋ค.
Constant Pool์์๋ ๊ธฐ์กด์ ๋ฐ์ดํฐ์ ๋ณ๊ฒฝ์ด ์๋ ์๋ก์ด ๋ฆฌํฐ๋ด์ ์ถ๊ฐ๊ฐ ๊ณ์ํด์ ์ด๋ฃจ์ด ์ง๋ค.
์์ ์ฝ๋์ ๊ฒฝ์ฐ, "1" , "12" , "123" , "1234"๊ฐ ๊ฐ๊ฐ String Constant Pool์ ์๋ก์ด ๋ฆฌํฐ๋ด๋ก ์ ์ฅ๋๋ฉฐ ์๋ฌด๋ ์ฐธ์กฐํ์ง ์์ ๋ฆฌํฐ๋ด์ GC๊ฐ ํ์ํด ๊ฐ๋ ๊ณผ์ ์ ๊ฑฐ์น๊ฒ ๋๋ค.
์ด๋ฌํ ๊ณผ์ ์ ์ฑ๋ฅ ์ ํ์ ์์ธ์ด ๋๋ค.
๐ค์ด๋ ๋ถ๋ถ์์ ์ฑ๋ฅ์ด ๋จ์ด์ง๋ค๋ ๊ฒ์ผ๊น?
์ฑ๋ฅ์ ๋ฐ์ง๋๋ ํญ์ ์๊ฐ๋ณต์ก๋๋ ๊ณต๊ฐ๋ณต์ก๋๋ฅผ ๋ฐ์ ธ์ผ ํ๋ค.
๊ฒฐ๋ก ๋ง ๋งํ์๋ฉด Java์์ String์ '+=' ๋๋ '+' ์ฐ์ฐ์ ๊ฒฝ์ฐ ์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค.
N์ ๊ธฐ์กด์ ๋ฌธ์์ด(lhs)์ ๊ธธ์ด, K๋ ๋ํ๋ ค๊ณ ํ๋ ๋ฌธ์์ด(rhs)์ ๊ธธ์ด๋ค.
์๋์ ์ฝ๋๋ฅผ ์์๋ก ์ฐ์ฐํ์์ ๋ํ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ณ์ฐํด๋ณด์.
s += "A"; ์์ i๋ฒ์งธ์์ s์ ๊ธธ์ด + "A"์ ๊ธธ์ด1 ๋งํผ์ ์๊ฐ์ด ์์๋๊ณ ๊ทธ๊ณผ์ ์ N๋ฒ๋งํผ ๋ฐ๋ณตํ๋ฏ๋ก
์ฐ์ฐํ์๋ N * (N+1) / 2 * N ์ด๊ณ , ์ด ์๊ฐ๋ณต์ก๋๋ ์ด ๋๋ค.
N * (N+1) / 2 ๋ 1๋ถํฐ N๊น์ง์ ํฉ, N์ ๋ฐ๋ณต๋ฌธ ํ์)
public class Main {
public static void main(String[] args) {
String str = "";
int n = 1000000;
for(int i = 0; i < n; i++){
s += "A";
}
}
}
์ด๋ฌํ '+' ์ฐ์ฐ์ StringBuffer ๋๋ StringBuilder๋ฅผ ์ด์ฉํ๋ฉด ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ ์ ํด๊ฒฐํ ์ ์์ผ๋ฉฐ
์์ ์ฝ๋๋ฅผ ์๋์ฒ๋ผ ๋ฐ๊พผ๋ค๋ฉด sb.append("A"); ์ ์๊ฐ๋ณต์ก๋๋ ์ด ๋๋ฏ๋ก ์ ์ฒด ์๊ฐ๋ณต์ก๋๋ฅผ ์ผ๋ก ์ค์ผ ์ ์๋ ํจ๊ณผ๋ฅผ ๊ฐ์ ธ์จ๋ค !
public class Main {
public static void main(String[] args) {
StringBuider sb = new StringBuider();
int n = 1000000;
for(int i = 0; i < n; i++){
sb.append("A");
}
}
}
String ๋ด์ฅํจ์ replace์ ์๊ฐ๋ณต์ก๋๋ O(๋ฌธ์์ด์ ๊ธธ์ด * (๊ต์ฒดํ ๋ฌธ์์ด์ ๊ธธ์ด + ๊ต์ฒด๋๋ ๋ฌธ์์ด์ ๊ธธ์ด/๊ต์ฒดํ ๋ฌธ์์ด์ ๊ธธ์ด))์ด๋ค.
์ฆ, str.replace(a, b)๋ผ๋ฉด O(len(str) * (len(a) + len(b)/len(a)))์ด๋ค.
replace ํจ์๋ ๋ฌธ์์ด str์ ๊ธธ์ด๋งํผ ์ ์ฒด์ ์ผ๋ก ๋ฌธ์์ด์ ํ๋์ฉ ํ์ํ๊ณ ๊ต์ฒดํ ๋ฌธ์์ด์ ๊ธธ์ด๋งํผ ์ด์ ๊ฐ์ ํ์ํด์ ๊ต์ฒดํด์ผํ๋ ๋ฌธ์์ด์ธ์ง ์๋์ง๋ฅผ ํ๋ณํ๋ค.
๊ต์ฒดํด์ผ ํ๋ ๊ฒฝ์ฐ, ๊ต์ฒด๋๋ ๋ฌธ์์ด์ ๊ธธ์ด์ ๋ฐ๋ผ ์ถ๊ฐ ์ฐ์ฐ์ด ํ์ํ๋ค.
๊ต์ฒด๋๋ ๋ฌธ์์ด์ ๊ธธ์ด๊ฐ ๊ต์ฒดํ ๋ฌธ์์ด์ ๊ธธ์ด์ ๊ฐ์ ๊ฒฝ์ฐ, ํ ๋น๋ ๊ธธ์ด๋งํผ(๊ต์ฒดํ ๋ฌธ์์ด์ ๊ธธ์ด๋งํผ)๋ง ์ฐ์ฐ์ ์ํํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ O(len(b) / len(a)) = O(1)๋ก ์์์ ์๊ฐ์ด ์์๋๋ค.
๊ต์ฒด๋๋ ๋ฌธ์์ด์ ๊ธธ์ด๊ฐ ๊ต์ฒดํ ๋ฌธ์์ด์ ๊ธธ์ด๋ณด๋ค ํฐ ๊ฒฝ์ฐ, ์ด๊ณผ๋ ๊ธธ์ด๋งํผ ์ ์์น๋ฅผ ๋ง๋ค๊ณ ๊ต์ฒด๊ฐ ์ด๋ค์ง๋ฏ๋ก O(len(b) / len(a))๋งํผ์ ์ถ๊ฐ ์ฐ์ฐ์ด ์์๋๋ค. ๋ฐ๋ผ์ ์ด ๊ฒฝ์ฐ๊ฐ ์ต์ ์ ๊ฒฝ์ฐ๋ค.
๋ง๋ฌด๋ฆฌ
String์ ์ด์ฉํ๋ฉด ๋ฌธ์์ด์ ๋ฆฌํฐ๋ด๋ก ์ด๊ธฐํ ํ ์ ์์ด ๋น ๋ฅด๊ฒ ์์ฑ์ด ๊ฐ๋ฅํ๊ณ
๋ฆฌํฐ๋ด์ ๋ถ๋ณํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฌ์ฉํ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ ์๋ชจ๊ฐ ์ ๋ค๋ ์ฅ์ ์ด ์์๋ค.
ํ์ง๋ง String์ ๋ฌธ์์ด ์ถ๊ฐ ์ฐ์ฐ์ ๋๋ฆฌ๊ณ ์ถ๊ฐํ ๋๋ง๋ค ๋งค๋ฒ ์๋ก์ด ๋ฌธ์์ด์ ์ถ๊ฐํ๊ธฐ ๋๋ฌธ์
์ฆ์ ๋ณ๊ฒฝ์ด ์ด๋ฃจ์ด ์ง๋ค๋ฉด StringBuffer๋๋ StringBuilder๋ฅผ ์ฌ์ฉํ๋๊ฒ์ด ์ข๋ค.
๋ํ
StringBuffer์ StringBuilder์์ ์ฐจ์ด์ ์ thread-safe์ ์ ๋ฌด์ด๋ค.
StringBuffer๊ฐ thread-safeํ๋ค.
๋ถ๋ฅ | String | StringBuffer | StringBuilder |
๋ณ๊ฒฝ | Immutable | Mutable | Mutable |
๋๊ธฐํ | Synchronized ๊ฐ๋ฅ (Thread-safe) | Synchronized ๋ถ๊ฐ๋ฅ. |
๋ฐ๋ผ์ ์ด ํ๋ฒ๊ฑฐ ๋ง๋ค๊ธฐ ๋ฌธ์ ๋ String์ replaceFirst๋ฅผ StringBuilder ๋ฅผ ์ฐ๋ฉฐ ํ ์ ์๋์ง ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ์ธ์งํ๊ณ ์๋์ง๋ฅผ ๋ฌป๋ ๋ฌธ์ ์ด๋ค.
๐์ฐธ๊ณ
https://hwayomingdlog.tistory.com/134
https://barbera.tistory.com/45
๋๊ธ