python刷题-双排序保证严格递增+for循环中增删元素对索引的影响

1.题目

你正在参加一个多角色游戏,每个角色都有两个主要属性:攻击 和 防御 。给你一个二维整数数组 properties ,其中 properties[i] = [attacki, defensei] 表示游戏中第 i 个角色的属性。

如果存在一个其他角色的攻击和防御等级 都严格高于 该角色的攻击和防御等级,则认为该角色为 弱角色 。更正式地,如果认为角色 i 弱于 存在的另一个角色 j ,那么 attackj > attacki 且 defensej > defensei 。

返回 弱角色 的数量。

 

示例 1:

输入:properties = [[5,5],[6,3],[3,6]]
输出:0
解释:不存在攻击和防御都严格高于其他角色的角色。
示例 2:

输入:properties = [[2,2],[3,3]]
输出:1
解释:第一个角色是弱角色,因为第二个角色的攻击和防御严格大于该角色。
示例 3:

输入:properties = [[1,5],[10,4],[4,3]]
输出:1
解释:第三个角色是弱角色,因为第二个角色的攻击和防御严格大于该角色。
 

提示:

2 <= properties.length <= 105
properties[i].length == 2
1 <= attacki, defensei <= 105

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/the-number-of-weak-characters-in-the-game
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2.个人题解

双排序保证严格递增

class Solution:
    def numberOfWeakCharacters(self, properties) -> int:
        temp = sorted(properties, key=lambda x: (-x[0], x[1]))  # X[0]降序,X[1]升序  保证了在X[0]相同时,不会遍历到误导项
        king = temp[0]
        count = 0
        for i in range(1, len(temp)):
            if king[1] > temp[i][1] :
                count += 1
            if king[1] < temp[i][1]:
                king = temp[i]

        return count

3.错误题解

# 错误题解1(思路错误)
class Solution:
    def numberOfWeakCharacters(self, properties) -> int:
        king = properties[-1]
        count = 0
        for i in range(len(properties)-2, -1, -1):  # 注意第二个参数一定要是-1(截止位置) 因为对于range来说(切片也是一样)range(0, 10)表示遍历0-9 所以上限值要多一个 对应的该例子中则是要比截止为止0还要小一个
            # if king > properties[i]:  # 注意列表不能像这样比大小达到预期结果,目前测试列表比的是里面元素和的大小
            #if king[0] > properties[i, 0] and king[0] > properties[i, 1]:  记住列表的索引规范
                # TypeError: list indices must be integers or slices, not tuple
            if king[0] > properties[i][0] and king[1] > properties[i][1]:
                del properties[i]
                count += 1
            if king[0] <= properties[i][0] and king[1] <= properties[i][1]:
                king = properties[i]

        for i in properties:
            if king[0] > i[0] and king[1] > i[1]:
                count += 1

        return count

#错误题解2 (时间损耗太大)
class Solution:
    def numberOfWeakCharacters(self, properties) -> int:
        count = 0
        for i in properties:
            for j in properties:
                if i[0] < j[0] and i[1] < j[1]:
                    properties.remove(i)   # 注意 如该例中的for循环在迭代的过程中实质上还是按照索引下标进行循环,这里我如果直接remove掉一个元素,那么该迭代对象的
                                           # 长度也发生变化,那么假设原本该迭代到2这个位置,因为迭代对象的长度发生了变化,所以现在的位置2相当于一开始的位置3,就会发生如该题所示跳过元素的现象
                    count += 1
                    break

        return count


for i in properties:

如上式所示for循环对迭代对象进行迭代时,其实质上还是按照索引去迭代,所以在删除某元素时会出现代码块中的问题

所以在进行增删的时候一定要注意列表元素数量的变化对索引的影响。

可以考虑用逆序的方式,如:

lists = [1,1,2,3,4,6,9,6,2,2]
lists.sort()
t = lists[-1]
for i in range(len(lists)-2,-1,-1):   # 逆序解决上述for循环的问题(索引溢出)
    # print(i)
    if t == lists[i]:
# del lists[i]
	    lists.remove(lists[i])
    else:
	    t = lists[i]
print(lists)

4.官方题解

# 官方题解
class Solution:
    def numberOfWeakCharacters(self, properties) -> int:  # 用字典去保存同一攻击的对象,每次比较时只拿之前的防御最大值去比
        import collections
        map_ = collections.defaultdict(list)
        # 防御力为0,需要记录一个防御力最大的单位
        # 逻辑很简单:只要你的防御力不是最强,而攻击力已经排序了,你又肯定比他们低
        max_defence = - 2 ** 31
        for attack, defence in properties:
            map_[attack].append(defence)
        count = 0
        for attack in sorted(map_, reverse=True):
            for defence in map_[attack]:
                if defence < max_defence:
                    count += 1
            # 刷新防御
            max_defence = max(max_defence, max(map_[attack]))
        return count

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值