0
点赞
收藏
分享

微信扫一扫

Leetcode-分治法/二分法

夜空一星 2022-02-10 阅读 55
leetcode

文章目录


q23 合并k个排序链表


题目传送门


题解

使用分治的思想去解决,即归并排序。因为有k个链表,所以遍历这个链表数组,然后逐个排序即可。

func mergeKLists(lists []*ListNode) *ListNode {
	if len(lists) == 0 {
		return nil
	}
	if len(lists) == 1 {
		return lists[0]
	}
	var L *ListNode
	L = mergeList(lists[0], lists[1])
	for i := 2; i < len(lists); i++ {
		L = mergeList(L, lists[i])
	}
	return L
}

func mergeList(L1, L2 *ListNode) *ListNode {
	L := &ListNode{}
	curr := L
	var next *ListNode
	for L1 != nil && L2 != nil {
		if L1.Val < L2.Val {
			next = L1.Next
			curr.Next = L1
			L1.Next = nil
			L1 = next
		} else {
			next = L2.Next
			curr.Next = L2
			L2.Next = nil
			L2 = next
		}
		curr = curr.Next
	}
	if L1 != nil {
		curr.Next = L1
	}
	if L2 != nil {
		curr.Next = L2
	}
	return L.Next
}




q33 搜索旋转排序数组


题目传送门


题解

这道题中,数组不是全局有序,而是局部有序,但是仍然可以使用二分来解决。
可以发现我们旋转数组的时候,一定有一部分的数组是有序的,比如示例中:数组变成了 [4, 5, 6] 和 [7, 0, 1, 2] 两个部分,其中左边 [4, 5, 6] 这个部分的数组是有序的。
所以在循环时我们可以查看被mid分开的两边,哪边是有序的,并判断target是否在有序的这边,如果不在有序的这边,那就一定在另一边。通过这个思路最终得到答案。

func search(nums []int, target int) int {
	n := len(nums)
	if n == 0 {
		return -1
	}
	if n == 1 {
		if target == nums[0] {
			return 0
		} else {
			return -1
		}
	}
	l, r := 0, n - 1
	for l <= r {
		mid := (l + r) / 2
		if nums[mid] == target {
			return mid
		}
		// 如果左边有序
		if nums[0] <= nums[mid] {
			// 如果target恰好在左边区间
			if nums[0] <= target && target < nums[mid] {
				r = mid - 1
			} else {
				l = mid + 1
			}
		// 如果右边有序
		} else {
			// 如果target恰好在右边区间
			if nums[mid] < target && target <= nums[n - 1] {
				l = mid + 1
			} else {
				r = mid - 1
			}
		}
	}
	return -1
}

q34 在排序数组中查找元素的第一个和最后一个位置


题目传送门


题解

首先使用二分找到值为target的下标midIndex,然后以midIndex为中点,左右寻找target的左右边界。

func searchRange(nums []int, target int) []int {
	l, r, midIndex, n := 0, len(nums) - 1, -1, len(nums)
	for l <= r {
		mid := (l + r) / 2
		if nums[mid] == target {
			midIndex = mid
			break
		}
		if nums[mid] < target && target <= nums[n - 1] {
			l = mid + 1
		} else {
			r = mid - 1
		}
	}
	if midIndex == -1 {
		return []int{-1, -1}
	}

	start, end := 0, 0
	for i := midIndex; i >= 0; i--{
		if nums[i] == target {
			start = i
		} else {
			break
		}
	}
	for i := midIndex; i <= n - 1; i++{
		if nums[i] == target {
			end = i
		} else {
			break
		}
	}
	return []int{start, end}
}

举报

相关推荐

0 条评论