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] }