229. 多数元素 II

该博客解析了一个力扣题目,通过采用类似于“羊了个羊”的消除策略,找到数组中数量超过数组长度三分之一的元素。算法使用了两次遍历,时间复杂度为O(n),空间复杂度为O(1)。最终返回可能的多数元素列表,经过验证确保至少有一个元素满足条件。
摘要由CSDN通过智能技术生成

题目链接:力扣

思路:数据大于floor(n/3)向下取整的数最多只有两个(仔细想想),或者1个,或者没有。这样的话就采取类似最近很火的游戏“羊了个羊”消除,当然区别就是我们槽位只有2个,点击第三个的时候只有不一样这三个才会同时消除,如果相同就叠在对应的槽位上,这样最后剩下的两个槽位上面的值才有可能大于floor(n/3),为什么说有可能,因为存在一种特殊情况:【3,2,3】,这种情况下通过我们的算法最后会出现,第一个槽位剩下3,第二个槽位剩下2,但是只有3是满足的,所以最后我们再把这两个值验证一下即可。别的能消除的一定不会大于floor(n/3),因为消除的是三个不一样的数。

两次for循环,所以时间复杂度为O(n)。

空间上面我们只开了几个变量,所以时间复杂度O(1)。

上代码:

class Solution {
    fun majorityElement(nums: IntArray): List<Int> {
        val count = nums.size / 3
        var numOne: Int? = null
        var numTwo: Int? = null
        var numOneCount = 0
        var numTwoCount = 0
        nums.forEach { x ->
            when (x) {
                numOne -> numOneCount++
                numTwo -> numTwoCount++
                else -> {
                    when (null) {
                        numOne -> {
                            numOne = x
                            numOneCount++
                        }
                        numTwo -> {
                            numTwo = x
                            numTwoCount++
                        }
                        else -> {
                            numOneCount--
                            if (numOneCount == 0) numOne = null
                            numTwoCount--
                            if (numTwoCount == 0) numTwo = null
                        }
                    }
                }
            }
        }
        numOneCount = 0
        numTwoCount = 0
        nums.forEach { x ->
            when {
                numOne != null && x == numOne -> numOneCount++
                numTwo != null && x == numTwo -> numTwoCount++
            }
        }
        val list = mutableListOf<Int>()
        if (numOneCount > count) numOne?.let { list.add(it) }
        if (numTwoCount > count) numTwo?.let { list.add(it) }
        return list
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心脏dance

如果解决了您的疑惑,谢谢打赏呦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值