LeetCode.1996 游戏中弱角色的数量

Ok 梳理一下思路,先按照攻击力进行排序,攻击力相同的按照防御力升序排序

if n[i].att == n[j].att {
    return n[i].def < n[j].def
}
return n[i].att < n[j].att

  


[{1 27} {3 60} {9 26} {14 6} {19 59} {21 27} {21 51} {26 91} {27 84} {34 48} {47 48} {47 77} {52 29} {53 10} {56 90} {57 24} {58 68} {59 5} {59 97} {63 39} {63 41} {64 61} {69 25} {69 55} {89 52} {90 9} {93 33} {97 29}]


从末尾开始向前遍历,如果后面的元素完全大于当前元素(攻击力以及防御力都大于),则res++


这么算下来,排序时间复杂度O(nlogn),两重循环遍历判断时间复杂度O(n2),提交代码TLE。

考虑优化方案。


重点考虑优化循环判断的时间复杂度O(n2)

考虑一遍循环判断出来是否有元素 完全大于当前元素。因为攻击力已经是升序排序,那么从后往前遍历的时候只需要关注防御力是否小于即可,另外,因为防御力整体是无序的,从后往前遍历的时候记录防御力最大值即可,注意到一种例外情况,就是当攻击力相同的时候,如果防御力max位于攻击力相同的其他角色,那其实当前角色并不是弱角色。为了解决这种情况,考虑当攻击力相同的时候,将防御力降序排序,那么就不会出现(Xattacki = Yattackj && Xdefencei < Ydefencej)[ i < j ],于是遍历一遍即可得到结果。

 

func numberOfWeakCharacters(properties [][]int) int {
	nodes := make(Nodes, 0, len(properties))
	for i := 0; i < len(properties); i++ {
		nodes = append(nodes, Node{
			att: properties[i][0],
			def: properties[i][1],
		})
	}
	sort.Sort(nodes)
	ret := 0
	max := math.MinInt32
	for i := len(nodes) - 1; i >= 0; i-- {
		if nodes[i].def < max {
			ret++
		}
		max = Max(max, nodes[i].def)
	}
	return ret
}

func Max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

type Node struct {
	att int
	def int
}

type Nodes []Node

func (n Nodes) Less(i, j int) bool {
	if n[i].att == n[j].att {
		return n[i].def > n[j].def
	}
	return n[i].att < n[j].att
}

func (n Nodes) Len() int {
	return len(n)
}

func (n Nodes) Swap(i, j int) {
	n[i], n[j] = n[j], n[i]
}

  

 

posted @ 2022-01-28 16:45  丶Blank  阅读(21)  评论(0编辑  收藏  举报