반응형
기존 구간합을 구하기위해선 범위 안에 있는 모든 배열을 탐색해서 구해야하고 그 때마다 배열을 탐색해야한다.
하지만 세그먼트트리는 다이나믹프로그래밍의 일종으로 작은 단위부터 더해가서 각각 구간들의 합을 저장한다.
구간합은 Binary Tree 와 재귀를 사용해서 만들수가 있다.
구간합을 구하는 Tree 의 크기는 2^k >= N (n은 배열의 수) 를 만족하는 가장 작은 k값을 구하고
2^k *2 한것이 Tree의 크기가 된다. 생각하기싫은 N*4의 크기로 할당하면 된다.
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
29
30
31
32
33
34
35
36
|
public class Segment {
static int arr[] = {3,5,6,7,2,9,4,5,2,8,1,5};
static int node[];
public static void main(String[] args) {
int N = 12;
//공간아 N*4 공간으로 활당한다 정확히는 2^k >=N 을 만족하는 k * 2 의 크기로 활당한다 여기서는 32
//2 ^ (log2 (N) + 1 ) *2 하면 정확한 크기 연산가능
node = new int[12*4];
//init
// 시작 인덱스, 끝인덱스 , 노드 번호
Init(0,N-1,1);
System.out.println(node[1]);
}
public static int Init(int start, int end, int n) {
if(start==end) {
return node[n] = arr[start];
}
int mid = (start + end) / 2;
return node[n] = Init(start,mid,n*2) + Init(mid+1,end,n*2+1);
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
부모의 노드 *2 -> 왼쪽 자식의 노드 , 부모의 노드*2+1 -> 오른쪽 자식의 노드이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public static int sum(int start, int end, int i, int j, int n) {
if (start == i && end == j) {
return node[n];
}
int mid = (start + end) / 2;
if (i <= mid && j <= mid) {
return sum(start, mid, i, j, n * 2);
} else if (i > mid) {
return sum(mid + 1, end, i, j, n * 2 + 1);
} else {
return sum(start, mid, i, mid, n * 2) + sum(mid + 1, end, mid + 1, j, n * 2 + 1);
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
구간합 구하는 함수. 지관적으로 구할려는 i,j에맞게끔 재귀를 분리하였다. 찾아보니 더간결한 소스가 있어서 밑에 첨부.
반응형
'Algorithm' 카테고리의 다른 글
페르마의 소정리 , 확장 유클리드 (0) | 2020.03.02 |
---|---|
JAVA : heap (삽입,삭제) (0) | 2020.03.01 |
트리의 지름 (0) | 2020.02.24 |
DFS를 Stack을 이용해서 풀어보자. (0) | 2020.02.13 |
유니온 파인드 : JAVA (0) | 2020.02.12 |