최대 연속 수의 부분 집합
3135 단어 프로그래머 필기시험 면접알고리즘 과 데이터 구조
정수 배열 에 가장 많은 연속 수 를 포함 하 는 부분 집합 을 찾 습 니 다. 예 를 들 어 15, 7, 12, 6, 14, 13, 9, 11 을 주면 5: [11, 12, 13, 14, 15] 로 돌아 갑 니 다.가장 쉬 운 방법 은 sort 다음 에 한 번 스 캔 하 는 것 입 니 다. 그런데 o (nlgn) 를 원 합 니 다. O (n) 방법 이 있 습 니까?
분석:
우 리 는 먼저 집합 이라는 데이터 구 조 를 배 웁 니 다.
그리고 집합 (Disjoint set 또는 Union - find set) 은 간단 하고 용도 가 광범 위 한 알고리즘 과 데이터 구조 이다.그리고 조사 집 은 몇 개의 교차 하지 않 는 집합 으로 비교적 빠 른 합병 과 요소 가 있 는 집합 을 판단 하 는 작업 을 실현 할 수 있 고 응용 이 많다. 예 를 들 어 그림 이 없 는 연결 분량 의 갯 수 등 이다.
그리고 조사 집 은 다음 과 같은 세 가지 조작 을 편리 하 게 할 수 있다.
1、Make_Set (x) 모든 요 소 를 하나의 집합 으로 초기 화 합 니 다.
초기 화 된 후에 모든 요소 의 아버지 노드 는 그 자체 이 고 모든 요소 의 조상 노드 도 그 자체 이다 (상황 에 따라 변 할 수도 있다).
2、Find_Set (x) 요소 가 있 는 집합 찾기
원소 가 있 는 집합 을 찾 는데 그 정 수 는 이 원소 가 있 는 집합 을 찾 은 조상 이다.이것 이 야 말로 판단 과 합병 의 최종 근 거 를 수집 하 는 것 이다.
두 원소 가 같은 집합 에 속 하 는 지 아 닌 지 를 판단 하고 그들 이 모인 조상 이 같은 지 를 보면 된다.
두 집합 을 합 친 것 도 한 집합 조상 을 다른 집합 조상 으로 만 드 는 것 으로 구체 적 으로 설명 도 를 볼 수 있다.
3. Union (x, y) 합병 x, y 가 있 는 두 개의 집합
두 개의 교차 하지 않 는 집합 을 합병 하 는 것 은 매우 간단 하 다.
Find 이용셋 은 두 집합 조상 을 찾 아 한 집합 조상 을 다른 집합 조상 에 게 가 리 켰 다.그림 과 같다
그리고 집합 최적화:
1、Find_설정 (x) 시 경로 압축
조상 을 찾 을 때 우 리 는 일반적으로 재 귀적 으로 찾 지만 요소 가 많 거나 나무 전체 가 하나의 사슬 로 변 할 때 매번 FindSet (x) 는 모두 O (n) 의 복잡 도 입 니 다. 이 복잡 도 를 줄 일 방법 이 있 습 니까?
답 은 긍정 적 이다. 이것 이 바로 경로 압축 이다. 즉, 우리 가 '전달' 을 통 해 조상 노드 를 찾 은 후에 '역 추적' 을 할 때 그의 자손 노드 를 조상 에 게 직접 가리 키 는 것 이다. 그러면 나중에 다시 FindSet (x) 시 복잡 도 는 O (1) 가 됩 니 다. 다음 그림 과 같 습 니 다.이 를 통 해 알 수 있 듯 이 경로 압축 은 이후 의 찾기 에 편리 하 다.
2. 유 니 온 (x, y) 시 순서대로 합병
즉, 합 칠 때 요소 가 적은 집합 을 요소 가 많은 집합 에 합 쳐 합 친 후에 나무의 높이 가 상대 적 으로 작 을 것 이다.
배경 지식 이 생기 면 우 리 는 그것 을 어떻게 이용 하여 이 문 제 를 해결 하 는 지 보 자.
우선, MakeSet (x) 는 모든 요 소 를 하나 로 바 꾸 고 집합 을 검사 한 다음 에 Union (x - 1, x), Union (x, x + 1) 을 스 캔 합 니 다.
다음 문 제 는 x - 1, x + 1 의 위 치 를 어떻게 빨리 찾 느 냐 하 는 것 이다.상수 복잡 도 를 찾 는 해시 표를 도입 해 야 한다.
#include
#include
using namespace std;
const int MAX = 100;
int Father[MAX];
int Rank[MAX];
void MakeSet(int x){
Father[x] = x;
Rank[x] = 1;
}
int FindFather(int x){
if(x != Father[x])
Father[x] = FindFather(Father[x]);
return Father[x];
}
void Union(int x, int y){
int a = FindFather(x);
int b = FindFather(y);
if(a == b)
return;
else{
int ar = Rank[a];
int br = Rank[b];
if(ar <= br){
Father[a] = b;
Rank[b] += Rank[a];
}else{
Father[b] = a;
Rank[a] += Rank[b];
}
}
}
int main()
{
const int length = 15;
int arr[length] = {15, 7, 12, 6, 14, 13, 10, 11, 4, 5, 8, 3, 2, 16, 17};
hash_map ihmap;
for(int i = 0; i < length; ++i)
{
MakeSet(i);
ihmap[arr[i]]=i;
}
for(int i = 0; i < length; ++i)
{
hash_map::iterator tmp;
tmp = ihmap.find(arr[i]-1);
if(tmp != ihmap.end())
{
Union(i,tmp->second);
}
tmp = ihmap.find(arr[i]+1);
if(tmp != ihmap.end())
{
Union(i,tmp->second);
}
}
int max = Rank[0];
int father = 0;
for(int i = 1; i< length; ++i)
if(Rank[i]>max){
max = Rank[i];
father = i;
}
cout<
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Python 3 상용 데이터 구조 구현Python 3 상용 데이터 구조 구현 전에 공부 Python 할 때 연습 코드 로 했 어 요.창고, 대기 열, 나무, 그림 등의 상용 데이터 구 조 를 실현 하고 BFS, DFS, 최 단 로 등 상용 알고리즘 을 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.