완전 탐색 알고리즘의 한 종류이지만 완전 탐색의 또 다른 이름으로 쓰이기도 한다.
브루트 포스 알고리즘은 완전탐색으로 답을 도출하는 알고리즘이며,
대부분은 반복문과 조건문을 통하여 답을 도출한다.
장점: 모든 경우의 수를 전부 탐색하기 때문에, 100%의 정확성을 보장한다.
단점: 모든 경우의 수를 전부 탐색하기 때문에, 높은 시간 복잡도를 갖는다.
브루트 포스와 완전탐색은 의미차이가 거의 없기 때문에 때때로 같은 의미로 쓰이기도 한다.
하지만, 이 둘은 아주 작은 차이가 있다.
먼저, 완전 탐색 알고리즘은 모든 경우의 수를 전부 탐색하는 방식의 알고리즘을 칭하며, 그 결과를 찾는 것보다 탐색한다는 과정에 중점을 둔다.
하지만 브루트포스 알고리즘은 문제를 해결 하기 위하여, 모든 경우를 탐색하고 답을 도출하는 알고리즘으로, 결과를 찾는 것에 중점을 둔다.
따라서 주 된 목적이 탐색과정이냐, 답을 도출하는 것이냐의 차이점이 있다.
선형구조란 자료를 구성하는 데이터를 순차적으로 나열시킨 형태다.

문제에 등장하는 자료구조가 선형구조라면 다음과 같은 순서로 풀이하면된다.
1. 주어진 문제를 선형구조로 바꾼다.
2. 자료들을 구조에 맞는 방법으로 해를 구할 때까지 탐색한다.
3. 탐색된 해를 문제 출력 조건에 맞게 출력한다.
1부터 100까지의 숫자 중에서 2로 나누어 떨어지고(짝수이고), 9로 나누어 떨어지는 숫자를 구하는 예시
public class SimpleBruteForceExample {
public static void main(String[] args) {
// 1부터 100까지 숫자를 하나씩 확인한다.
for (int i = 1; i <= 100; i++) {
// 숫자가 2로 나누어 떨어지고(짝수이고), 9로도 나누어 떨어지면 출력한다.
if (i % 2 == 0 && i % 9 == 0) {
System.out.println(i);
}
}
}
}
5 팩토리얼을 구하는 예시
public class Example {
public static void main(String[] args) {
System.out.println("5 factorial = " + factorial(5));
}
public static int factorial(int n) {
if (n == 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}
}
5 factorial(4) 호출됨.
이는 4 factorial(3)을 호출함.
그 다음 3 factorial(2)를 호출함.
그 다음 2 factorial(1)을 호출함.
factorial(1)은 기본 조건에 도달하여 1을 반환함.
factorial(1)은 1을 반환 (기본 단계)
factorial(2)는 2 factorial(1)이 되므로, 2 1 = 2
factorial(3)는 3 factorial(2)이 되므로, 3 2 = 6
factorial(4)는 4 factorial(3)이 되므로, 4 6 = 24
factorial(5)는 5 factorial(4)이 되므로, 5 24 = 120
이렇게 재귀함수로 모든 경우의 수를 탐색할 수 있음.
최선의 경우(Best case): 찾고자 하는 요소가 자료구조의 첫 번째 위치에 있을 때다. 이 경우, 단 한 번의 비교만으로 원하는 값을 찾을 수 있으므로, 최선의 경우의 시간 복잡도는 (O(1))다.
평균적인 경우(Average case): 평균적으로 찾고자 하는 요소가 자료구조의 중간 부근에 위치할 가능성이 있으므로, 평균적인 시간 복잡도도 (O(n))으로 볼 수 있다.
최악의 경우(Worst case): 찾고자 하는 요소가 자료구조의 마지막에 위치하거나 아예 존재하지 않을 때다. 이 경우, 모든 요소를 검사해야 하므로 최악의 경우의 시간 복잡도는 (O(n))다.

DFS, BFS의 시간복잡도와 동일하다.
결국 브루트 포스는 모든 경우의 수를 탐색해야 하기 때문에,
만약 탐색해야 할 요소의 숫자가 엄청 크다면 시간복잡도는 그에 비례하여 매우 커질 수 있다.
따라서 가장 좋은 방법은 모든 경우를 탐색하면서 각 경우에서 불필요한 연산을 하지 않는 것이 중요하다.
브루트포스의 풀이 방법은 문제에 등장하는 자료구조가 선형/비선형에 따라 나뉜다. 선형이라면, 순차탐색(반복문, 재귀함수)을 하면 되고 비선형 알고리즘이라면 dfs,bfs를 사용하여 풀이하면 된다. 단, 불필요한 연산은 최대한 피할 수 있으면 피하는 것이 베스트다.


없음.
answer의 길이와 찍기 수열의 길이가 다른데 도대체 어떻게 비교해야 할지 몰랐다.
예를 들어, 찍기 수열이
{1,2,3,4,5} 이고
문제의 정답이
{5,4,3,2,1,5,4,3,2,1,5,4,3,2,1,5,4,3,2,1}
일 때 둘을 어떻게 비교해야 할지 떠오르지 않았다.
import java.util.*;
class Solution {
public List<Integer> solution(int[] answers) {
int[] first = {1, 2, 3, 4, 5};
int[] second = {2, 1, 2, 3, 2, 4, 2, 5};
int[] third = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
int[] score = {0, 0, 0};
// 점수 계산
for (int i = 0; i < answers.length; i++) {
if (answers[i] == first[i % 5]) {
score[0]++;
}
if (answers[i] == second[i % 8]) {
score[1]++;
}
if (answers[i] == third[i % 10]) {
score[2]++;
}
}
// 최대 점수 구하기
int max = Math.max(score[0], Math.max(score[1], score[2]));
// 최대 점수를 가진 수포자 리스트 생성
List<Integer> answer = new ArrayList<>();
for (int i = 0; i < 3; i++) {
if (max == score[i]) {
answer.add(i + 1);
}
}
return answer;
}
}
answers 배열의 길이를 n이라고 할 때, for 루프는 n번 반복한다.
-> O(N)
고정된 크기(3)의 배열을 순회하는 반복문
-> O(1)
따라서, 전체 코드의 시간 복잡도는 O(n) + O(1) = O(n)
int max = Math.max(score[0], Math.max(score[1], score[2]));
알다시피 max()는 두 개의 인자를 받는데, 세 개는 어떻게 받아야할까?
쉽다. 두번째 인자로 Math.max(비교값1,비교값2)를 넣으면 된다.
네개의 점수들도 마찬가지 일 것이다.
Math.max(Math.max(score[0],score[1]), Math.max(score[2],score[3]));
https://olrlobt.tistory.com/33
https://goodgid.github.io/DS-Linear-and-NonLinear/