ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1814. Count Nice Pairs in an Array (数学方法巧解,警惕时间复杂度思维陷阱)

2021-04-04 14:00:50  阅读:209  来源: 互联网

标签:1814 Count Pairs nums int 复杂度 rev freq 解法


简介

题目链接 Leetcode 1814. Count Nice Pairs in an Array

一旦看透题目的本质,这道题非常的简单。但是由于题目规定输入列表的尺寸在10的5次方这个范围,如下:

1 <= nums.length <= 10^5
0 <= nums[i] <= 10^9

会使解题者下意识的认为这题应该用堆栈(Heap),二分法,树之类的数据结构,但其实最终这题就是一个简单的O(N)解法,非常意外。被误导的过程如下:

  • 看到输入尺寸 -> 推断合理的时间复杂度 -> 利用时间复杂度找符合的解法和数据结构

所以,警惕输入尺寸带来先入为主的时间复杂度上的误导。尽管以上过程可以在多数时候帮助解题,但是不要被这样的模式限制自己的思维

注意:文章中一切注解皆为Python代码

理解题目

题目非常简单。给定一个列表,找出所有符合以下条件的对(Pairs),返回总共的对数,条件如下:

  • 0 <= i < j < nums.length
  • nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])

乍一看似乎只有O(N^2)的解法,甚至想不出O(NlogN)的解法,但其实简单的数学移项操作就能用O(N)完成这个问题。

把原公式,通过移项变成如下公式:

  • nums[i] - rev(nums[i]) == nums[j] - rev(nums[j])

因此,实现O(N)解法的步骤如下:

  • 我们需要用O(N)做一个新的列表,把其中每一个数字都反过来
  • 再对于每一个nums[i] - rev(nums[i])进行计数,这里可以用Python中的Counter或者单纯的dict
  • 接着对于每一个nums[i] - rev(nums[i])出现的频率,假定这个频率为freq,那么可以形成的对数为freq * (freq-1)
  • 最后返回对数总和即可

代码实现

class Solution:
    def countNicePairs(self, nums: List[int]) -> int:
        rev_nums = [int(str(num)[::-1]) for num in nums]
        c = collections.Counter([i-j for i, j in zip(nums, rev_nums)])
        return sum([freq * (freq-1) // 2 for _, freq in c.items() if freq > 1]) % int(1e9+7)

解题后的思考

经验固然重要,但不要被先入为主的经验限制了思考。

标签:1814,Count,Pairs,nums,int,复杂度,rev,freq,解法
来源: https://blog.csdn.net/tech_zwl/article/details/115426052

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有