나는 분리 된 간격 및 간격의 정렬 된 목록을가집니다. [(1, 5), (10, 15), (20, 25)] 및 (12, 27). 그래서, (12,27)은 간격입니다. [(1, 5), (10, 27)]와 같은 분리 된 간격의 정렬 된 목록으로 병합하려고합니다.분리 된 간격의 정렬 된 목록에 간격 삽입
답변
의사 : 당신은 실제로 당신의 간격이 노드이며, 그들이 공통 부분 (예를 들어 (12,27)가 연결되어있는 경우들이 서로 연결되어에서, 그래프 문제를 모델링 할 수
list = ...
u = (12,27)
i = 0
newlist = []
while (max(list[i]) < min(u)) //add all intervals before intersection
newlist.add(list[i++])
mini = i
while (min(list[i]) < max(u)) // skip all intersecting intervals
i++
maxi = i
newlist.add((min(list[mini],u),max(list[maxi],u)) // add the new interval
while (i < list.length) // add remaining intervals
newlist.add(list[i++])
return newlist
알고리즘이 작동하지 않습니다. list [(1,2), (4,6), (7,8), (16,17)] 및 insert (11,12)를 고려하십시오. 알고리즘은 간격 (7,12)을 만들지 만 간격 (9,10)이 없기 때문에 잘못되었습니다! 그 좋은 시도 – TimeToCodeTheRoad
미니 == 맥시 때 특별한 경우를 처리 할 필요가, 일반적인 아이디어는 동일하게 유지됩니다. – yurib
나는 이것이 매우 효율적이라고 생각하지 않는다. 삽입 위치에 대한 이진 검색이 순서대로 수행됩니다. – maasha
(15, 20))은 이제 제는 각 연결 컴포넌트에 시작 (예 10) 및 단부 의 최대 값 (예 : 25)의 최소값을 찾아 연결 컴포넌트를 찾을 것이다. Interval Graphs을 참조하는 것이 좋습니다.
여기에 vars로 가득 찬 비 관용적 인 스칼라 솔루션이 있습니다. 솔루션은 필자가해야 할 것보다 길어 보입니다. 왜냐하면 필자가 부가 작업만을 지원하는 목록에 추가 및 삽입을 수행하지 못하기 때문입니다.
- 스캔 새로운 간격 할 것들과 겹치지 않는 두리스트 것들에 간격 목록을 나누어 다음과 같이
ALGO이다. 겹치지 않는 간격은 새로운 간격 이후 또는 완전히 시작하기 전에 시작하는 간격입니다. 또한 우리가 새로운 간격을 삽입한다면, 그것보다 낮은 가장 높은 간격 이후에있을 것입니다. 이 단계에서 우리는 겹치는 간격 목록과 겹치지 않는 목록 목록을 가지고 있습니다.
- 중복이없는 경우 새 간격은 모든 주어진 간격보다 빠르거나 모든 간격 이후 또는 두 간격 사이에서 (여전히 겹치지 않음) 발생합니다.
- 중복되는 경우 새 간격으로 겹치는 간격을 병합하십시오. 겹치는 간격의 시작은 min (새 간격 시작, 가장 작은 겹침 간격 시작)입니다. 우리는 비슷하게 끝을 계산할 수 있습니다. 이제 이전에 계산 된 위치에 겹치는 간격을 삽입하십시오.
object trial { val intervals1 = List((1, 2), (4, 6), (7, 8), (16, 17))) val intervals2 = List((1, 5), (10, 15), (20, 25) val newInterval1 = (11, 12) val newInterval2 = (12, 27) // Interval algo test. val result1 = Merge(intervals1, newInterval1) // result1 : List((1,2), (4,6), (7,8), (11,12), (16,17)) val result2 = Merge(intervals2, newInterval2) // result2 : List[(Int, Int)] = List((1,5), (10,27)) } object Merge{ def append[T](list: List[T], el: T): List[T] = { (el :: list.reverse).reverse } def insert[T](list: List[T], pos: Int, elem: T): List[T] = { var newList = List.empty[T] val reversePos = list.length - pos list.reverse.zipWithIndex foreach { case(el, i) if i == reversePos => { newList = elem :: newList newList = el :: newList } case (el, i) => newList = el :: newList } newList } def apply(list: List[(Int, Int)], interval: (Int, Int)): List[(Int, Int)] = { val (min, max) = interval var newList = List.empty[(Int, Int)] // Store potentially overlapping stuff. var overlap = List.empty[(Int, Int)] // Maintain the position to begin merge. var posInsert = 0 list.zipWithIndex foreach { case(intervalz, i) => if (intervalz._2 < min) { // Does not overlap but an insert will be after the highest of these. posInsert = i newList = append(newList, intervalz) } else if (intervalz._1 > max) { // Does not overlap. newList = append(newList, intervalz) } else overlap = append(overlap, intervalz) } if (overlap isEmpty) { if (posInsert == 0) newList = interval :: newList else newList = insert(newList, posInsert + 1, interval) } else { // Start of new interval is the lower of the first overlap's start or the interval's start. val startOfInterval = Math.min(overlap.head._1, min) // Enf of interval is higher of last overlap's end or interval's end. val endOfInterval = Math.max(overlap.head._2, max) // Insert the merged interval after the highest interval smaller than the start of the new internval. if (posInsert == 0) newList = (startOfInterval, endOfInterval) :: newList else newList = insert(newList, posInsert + 1, (startOfInterval, endOfInterval)) } newList } }
그것은 여기에 언급 된 시험을 통과하고, O (N)이다 : 여기
코드이다.
EDIT. 알곤 버전 :
intervals = [....]
newInterval = (12, 27)
newList = []
overlappingList = []
posInsert = 0
i = 0
while (i < intervals.size)
if (intervals[i].max < newInterval.min)
posInsert = i
append(newList, intervals[i])
else if (intervals[i].min > newInterval.max)
append(newList, intervals[i])
else
append(overlappingList, intervals[i])
i++
if (overlap isEmpty)
if (posInsert == 0) prepend(newList, newInterval)
else insert(newList, posInsert + 1, newInterval)
else
start = Min(overlappingList[i].min, newInterval.min)
end = Max(overlappingList[i].max, newInterval.max)
if (posInsert == 0) prepend(newList, newInterval)
else insert(newList, posInsert + 1, new Interval(start, end))
return newList
- 1. 정렬 된 링크 목록에 삽입
- 2. 정렬 된 목록에 재귀 적으로 삽입
- 3. 정렬 된 링크 된 목록에 추가
- 4. 정렬 된 링크 된 목록에 요소 추가
- 5. 링크 된 간격 목록
- 6. 연속적으로 분리 된 단어로 목록에 공백 추가
- 7. 링크 된 목록을 사용하여 정렬 된 삽입
- 8. 정렬 된 DataGridView가있는 행 삽입
- 9. 정렬 된 배열에 숫자 삽입!
- 10. 단일 삽입 목록에 단순 삽입 정렬 C++
- 11. 겹침이없는 간격의 병합을 지원하는 간격 트리 알고리즘
- 12. 정렬 및 회전 목록에 요소 삽입
- 13. 정렬 목록에 포함 된 사용자 정의 유형이
- 14. 정렬 된 목록을 새 목록에 병합
- 15. 정렬 된 링크 목록에 숫자를 어떻게 추가합니까?
- 16. (목록에 포함 된) dicts를 Python으로 알파벳순으로 정렬
- 17. 정렬 된 목록에 RESTful 방식으로 주소 지정
- 18. 분리 된 요소의 녹아웃 바인딩
- 19. 시간 데이터가 포함 된 거의 정렬 된 목록에 대한 효율적인 정렬 알고리즘은 무엇입니까?
- 20. 링크 된 목록 삽입, 삭제, 정렬
- 21. X를 정렬 된 목록의 올바른 위치에 삽입
- 22. 링크 된 목록 cstring 삽입 정렬
- 23. SQL Server에서 여러 행을 쉼표로 분리 된 목록에 결합하려면 어떻게합니까?
- 24. 태그는 쉼표로 분리 된 값 또는 분리 된 표가있는 클래스입니까?
- 25. RDBMS에서 정렬 된 목록에 가장 적합한 데이터 구조는 무엇입니까?
- 26. CodeIgniter로 분리 된 데이터베이스
- 27. git에서 분리 된 헤드
- 28. 분리 된 문자열을 배열로?
- 29. 분리 된 부분
- 30. 분리 된 밑줄이 필요합니다.
정렬 된 정수 목록에 정수를 삽입하는 것과 다르지 않습니다. 그들은 둘 다 같은 방식으로 서로 비교 될 수 있습니다. – hugomg