这是悦乐书的第254次更新,第267篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第121题(顺位题号是532)。给定一个整数数组和一个整数k,您需要找到数组中唯一的k-diff对的数量。 这里k-diff对被定义为整数对(i,j),其中i和j都是数组中的数字,它们的绝对差是k。例如:

输入:[3,1,4,1,5],k = 2
输出:2
说明:数组中有两个2-diff对,(1,3)和(3,5)。虽然我们在输入中有两个1,但我们应该只返回唯一对的数量。

输入:[1,2,3,4,5],k = 1
输出:4
说明:数组中有四个1-diff对,(1,2),(2,3),(3,4)和(4,5)。

输入:[1,3,1,5,4],k = 0
输出:1
说明:数组中有一个0-diff对,(1,1)。

注意:

  • 对(i,j)和(j,i)计为同一对。

  • 数组的长度不会超过10,000。

  • 给定输入中的所有整数都属于以下范围:[-1e7, 1e7]。

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

暴力解法。先排序,然后使用两层循环,计算不同元素的绝对值,如果等于k,次数就加1。在外面第一层循环那里,如果前后元素相同,就跳过当前循环,进行下一次循环。在内层循环那里同样做了类似的判断,排除重复计算。

此解法的时间复杂度是O(n^2),空间复杂度是O(1)。

public int findPairs(int[] nums, int k) {if (nums == null || nums.length == 0 || k < 0) {return 0;}Arrays.sort(nums);int count = 0;for (int i=0; i<nums.length; i++) {int n = nums[i];if (i >= 1 && nums[i-1] == nums[i]) {continue;}for (int j=i+1; j<nums.length; j++) {if (j >= i+2 && nums[j-1] == nums[j]) {continue;}if (Math.abs(n - nums[j]) == k) {count++;}}}return count;
}

03 第二种解法

第一种解法时间复杂度太高了,得降低点。第一种解法,我们是做减法,求绝对值,来判断是否等于k,我们也可以做加法,拿当前元素加上k,然后看新元素是否存在于数组中。同时还要考虑重复的计算数据,因此参与计算的元素是唯一的,对此我们可以使用HashMap,已元素值作为key,该元素值出现次数为value。遍历key,如果key加上k后的值存在于map中,次数加1,另外如果k为0的时候,只需要判断每个key所对应的value是否大于等于2即可。

此解法的时间复杂度是O(n),最坏情况也可能是O(n^2),空间复杂度是O(n)。

public int findPairs2(int[] nums, int k) {if (nums == null || nums.length == 0 || k < 0) {return 0;}Map<Integer,Integer> map = new HashMap<Integer,Integer>();for (int n : nums) {map.put(n, map.getOrDefault(n, 0)+1);}int count = 0;if (k == 0) {for (Integer key: map.keySet()) {if (map.get(key) >= 2) {count++;}}} else {for (Integer key: map.keySet()) {if (map.containsKey(key+k)) {count++;}}}return count;
}

04 第三种解法

对于第二种解法,还可以将判断放在循环体里面。

public int findPairs3(int[] nums, int k) {if (nums == null || nums.length == 0 || k < 0) {return 0;}Map<Integer,Integer> map = new HashMap<Integer,Integer>();for (int n : nums) {map.put(n, map.getOrDefault(n, 0)+1);}int count = 0;for (Map.Entry<Integer, Integer> entry : map.entrySet()) {if (k == 0) {if (entry.getValue() >= 2) {count++;} } else {if (map.containsKey(entry.getKey()+k)) {count++;}}}return count;
}

05 第四种解法

使用HashSet。使用两个HashSet,同样分为两种情况:k等于0和K不等于0。

如果k等于0时,对数组进行遍历,如果当前元素不存在于set1中,就添加进set1,如果存在set1中,就去判断是否存在于set2中,如果不存在,次数就加1,并将元素添加进set2中。

如果k不等于0,遍历数组,将当前元素添加进set1,将当前元素加上k后再添加进set2,然后使用retainAll方法,将set1中不包含set2元素的元素剔除掉(也就是两set的交集),最后count等于set1中元素的个数。

public int findPairs4(int[] nums, int k) {if (nums == null || nums.length == 0 || k < 0) {return 0;}Set<Integer> set1 = new HashSet<Integer>();Set<Integer> set2 = new HashSet<Integer>();int count = 0;if (k == 0) {for (int n : nums) {if (!set1.contains(n)) {set1.add(n);} else {if (!set2.contains(n)){count++;}set2.add(n);}}} else {for (int n : nums) {set1.add(n);set2.add(n + k);}set1.retainAll(set2);count = set1.size();}return count;
}

06 第五种解法

使用双指针。还是先将数据排序,定义左右两个指针,分别从0开始,如果左右指针相等,说明是循环的第一次或者重复了,就需要将右指针往后移动一位。如果左指针所指向元素加上k后等于右指针的元素,那么次数加1,接着要判断,如果右指针所指向位置后面的元素和当前元素相等,那么右指针继续往后移动。如果左指针所指向元素加上k后小于右指针的元素,说明左边的元素小了,左指针向前移动。如果左指针所指向元素加上k后大于右指针的元素,说明右边的元素小了,右指针向前移动。

此解法的时间复杂度是O(n log(n)),空间复杂度是O(1)。

public int findPairs5(int[] nums, int k) {if (nums == null || nums.length == 0 || k < 0) {return 0;}Arrays.sort(nums);int count = 0;int start = 0, end = 0;while (end < nums.length) {if (start == end) {end++;} else if (nums[start] + k == nums[end]) {count++;while (end + 1 < nums.length && nums[end] == nums[end + 1]) {end++;}end++;} else if (nums[start] + k < nums[end]) {start++;} else if (nums[start] + k > nums[end]) {end++;}}return count;
}

07 小结

此题的测试用例中,k出现了负值,所以在特殊情况判断中,还需要判断k小于0,这也是本题不严谨的一个地方。

算法专题目前已日更超过三个月,算法题文章121+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

转载于:https://www.cnblogs.com/xiaochuan94/p/10399011.html

LeetCode算法题-K-diff Pairs in an Array(Java实现)相关推荐

  1. LeetCode算法题-Convert a Number to Hexadecimal(Java实现)

    这是悦乐书的第219次更新,第231篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第86题(顺位题号是405).给定一个整数,写一个算法将其转换为十六进制.对于负整数,使 ...

  2. LeetCode算法题-Minimum Depth of Binary Tree(Java实现)

    这是悦乐书的第168次更新,第170篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第27题(顺位题号是111).给定二叉树,找到它的最小深度.最小深度是沿从根节点到最近的 ...

  3. leetcode算法题--K站中转内最便宜的航班★

    原题链接:https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/ 1.递归(超时) 代码: int findCheapest ...

  4. leetcode算法题--K 个一组翻转链表

    原题链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/ ListNode* reverseList(ListNode* head ...

  5. leetcode算法题--K 次串联后最大子数组之和★

    原题链接:https://leetcode-cn.com/problems/k-concatenation-maximum-sum/ 如图(来源) 记k==1,数组和为sum 分情况讨论: 当k == ...

  6. LeetCode算法题-Reverse Linked List(Java实现)

    这是悦乐书的第192次更新,第195篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第51题(顺位题号是206).反转单链表.例如: 输入:1-> 2-> 3- ...

  7. leetcode算法题-- 买卖股票的最佳时机

    原题链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/ 这类股票题目请见leetcode算法题–最佳买卖股票时机含 ...

  8. leetcode算法题--不同的二叉搜索树

    原题链接:https://leetcode-cn.com/problems/unique-binary-search-trees/ 相关题目:leetcode算法题--不同的二叉搜索树 II 1.递归 ...

  9. LeetCode算法题整理(200题左右)

    目录 前言 一.树(17) 1.1.后序遍历 1.2.层次遍历 1.3.中序 1.4.前序 二.回溯(20) 2.1.普通回溯 2.2.线性回溯:组合.排列.子集.分割 2.3.矩阵回溯 三.二分查找 ...

最新文章

  1. 《数据库原理与应用》(第三版)第13章 安全管理 基础 习题参考答案
  2. 别不承认!搞懂那些数理原理,才发现它们和枯燥根本不沾边!
  3. Java 进阶——单例模式
  4. 桥本有菜java,深入浅出Extjs4.1.1(ExtJS组件、ExtJS对Ajax支持、ExtJS布局)配在线选课系统实战...
  5. 六步实现Spring.NET 与 NHibernate 的整合
  6. 大端和小端存储模式解析
  7. GIT 操作中 Reinitialized existing Git repository in.......解决方法?
  8. matlab遥感原理与应用,遥感原理与应用知识点概括考研.doc
  9. 安装C4D步骤 附加一大波C4D序列号
  10. ALSA 中 hw 和 plughw 的区别
  11. 视网膜正常oct图_眼底OCT分层|图文并茂教你看
  12. Pyhton opencv 图片裁剪
  13. 阿里云交互式分析与Presto对比分析及使用注意事项
  14. 学术-数学:费马猜想
  15. 动态规划:求两个字符串的最长公共子序列
  16. Ubuntu查看系统信息(CPU、GPU信息)
  17. 东华大学 oj1——求长方形的面积和周长
  18. 像素和分辨率是什么?
  19. DPDK 入门最佳指南
  20. 【2022新书】有趣的数据结构

热门文章

  1. 正则表达式格式化字符串
  2. 【C#】VS2012+InstallShield2013制作软件更新包
  3. CSS 中的各种居中 (水平、垂直)
  4. 设计模式之外观模式(Fasade Pattern)
  5. 硬件结构(中):EqualLogic PS5000 对等存储“动车组”
  6. Linux SendMail服务启动慢总结
  7. AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔)
  8. 了解一下JavaScript的未来——ECMAScript5
  9. 一些常用的CSS hack代码
  10. 带有无参数的存储过程