Leetcode-贪心

文章目录

    • q55 跳跃游戏
    • q406 根据升身高重建队列
    • q621 任务调度器


q55 跳跃游戏


题目传送门


题解

当我们跳到一个位置的时候,下一步该怎么跳?其实这个问题可以不用管,我们其实只需要关心每次跳跃能覆盖到的最大范围就可以了,当这个最大范围覆盖到了最后一个元素,那么直接返回true即可。
所以我采取的策略是:遍历数组,更新能覆盖到的最大范围值。同时还要做两个判断:

  • 如果某一个元素为0 且 能覆盖的最大范围不超过这个元素的位置,直接返回false
  • 覆盖范围超过最后一个元素的位置,直接返回true
func canJump(nums []int) bool {
	// 如果数组长度为1,直接返回true
	if len(nums) < 2 {
		return true
	}
	maxRange := 0
	for i := 0; i < len(nums) - 1; i++ {
		// 更新能覆盖到的最远值
		if i + nums[i] > maxRange {
			maxRange = i + nums[i]
		}
		// 如果某一个元素为0 且 能覆盖的最大范围不超过这个元素的位置,直接返回false
		if nums[i] == 0 && maxRange <= i {
			return false
		}
		// 覆盖范围超过最后一个元素的位置,直接返回true
		if maxRange >= len(nums) - 1 {
			return true
		}
	}
	return false
}

q406 根据升身高重建队列


题目传送门


题解

首先我们把二维数组根据一维逆序,二维正序的思路去排序,排序结束之后,所有人的前面都是比自己高的人;然后根据插入排序的思想,把每个人根据第二维,插入到相应的位置.

func reconstructQueue(people [][]int) (res [][]int) {
	// 根据一维逆序,二维正序
	sort.Slice(people, func(i, j int) bool {
		if people[i][0] == people[j][0] {
			return people[i][1] < people[j][1]
		}
		return people[i][0] > people[j][0]
	})
	res = make([][]int, 0)
	for _, v := range people {
		// 添加新元素到尾部
		res = append(res, v)
		// 把待插入位置的后面所有元素向后移动一位
		copy(res[v[1]+1:], res[v[1]:])
		// 将待插入元素插入到相应位置
		res[v[1]] = v
	}
	return res
}

q621 任务调度器


题目传送门


题解

首先找出出现次数最多的单词,比如是A.
然后冷却时间是n,假如n = 2,所以完成一次任务周期就是:

A _ _

设A出现的次数为maxCount,所以完成所有任务的时间就是res = (maxCount - 1) * (n + 1),但是如果有不止一个单词的出现次数为maxCount,那么依次res++.

还有一种情况就是,冷却时间小于单词的种类数,这个时候冷却时间是没有意义的,完成任务的时间就是len(tasks),所以最后我们需要比较一下reslen(tasks)的大小.

func leastInterval(tasks []byte, n int) int {
	var nums [26]int
	maxCount := 0
	// 统计每个字母的出现次数,并找出出现次数最多的字母
	for _, task := range tasks {
		nums[task-'A']++
		maxCount = max(nums[task-'A'], maxCount)
	}
	res := (maxCount - 1) * (n + 1)
	for i := 0; i < 26; i++ {
		if maxCount == nums[i] {
			res++
		}
	}
	return max(res, len(tasks))
}
func max(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

你可能感兴趣的:(LeetCode,leetcode)