Java怎么求三个数是否为零

77次阅读
没有评论

共计 2405 个字符,预计需要花费 7 分钟才能阅读完成。

本篇内容主要讲解“Java 怎么求三个数是否为零”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“Java 怎么求三个数是否为零”吧!

简单的做法,根据 2Sum,遍历 3 次,此时时间复杂度是 O(n 的 3 次方)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 * Created by lifei on 16/5/29.
 */
public class ThreeSum {
 /**
 *
 *  暴力解决法是每个人都能想到的,三层 for 循环,时间复杂度是 O(n^3),而且还要处理重复的问题,显然不是题目想要的解法。  那能不能降到 O(n^2)?排序算法的时间复杂度为 O(nlgn),小于 O(n^2),那么我们不妨先对数组排个序。 *
 *  排序之后,我们就可以对数组用两个指针分别从前后两端向中间扫描了,如果是  2Sum,我们找到两个指针之和为 target 就 OK 了, *  那  3Sum  类似,我们可以先固定一个数,然后找另外两个数之和为第一个数的相反数就可以了。 *
 *  做过 leetcode 的人都知道,  里面有 2sum, 3sum(closest), 4sum 等问题,  这些也是面试里面经典的问题,  考察是否能够合理利用排序这个性质,
 *  一步一步得到高效的算法.  经过总结,  本人觉得这些问题都可以使用一个通用的 K  sum 求和问题加以概括消化,
 *  这里我们先直接给出 K  Sum 的问题描述和算法(递归解法),  然后将这个一般性的方法套用到具体的 K,
 *  比如 leetcode 中的 2Sum, 3Sum, 4Sum 问题.  同时我们也给出另一种哈希算法的讨论.
 *
 *
 K Sum 求解方法,  适用 leetcode 2Sum, 3Sum, 4Sum:  方法一:  暴力,就是枚举所有的 K -subset,  那么这样的复杂度就是   从 N 选出 K 个,复杂度是 O(N^K)
  方法二:  排序
 2sum 的算法复杂度是 O(NlogN)  因为排序用了 N  log N 以及头尾指针的搜索是线性的,所以总体是 O(NlogN),  好了现在考虑 3sum,  有了 2sum 其实 3sum 就不难了,这样想:  先取出一个数,那么我只要在剩下的数字里面找到两个数字使得他们的和等于 (target –  那个取出的数) 就可以了吧。所以 3sum 就退化成了 2sum,
  取出一个数字,这样的数字有 N 个,所以 3sum 的算法复杂度就是 O(N^2 ),  注意这里复杂度是 N 平方,因为你排序只需要排一次,后面的工作都是取出一个数字,  然后找剩下的两个数字,找两个数字是 2sum 用头尾指针线性扫,这里很容易错误的将复杂度算成 O(N^2logN),这个是不对的。  我们继续的话 4sum 也就可以退化成 3sum 问题(copyright @sigmainfy),那么以此类推,K-sum 一步一步退化,最后也就是解决一个 2sum 的问题, K sum 的复杂度是 O(n^(K-1))。  这个界好像是最好的界了,也就是 K -sum 问题最好也就能做到 O(n^(K-1))复杂度
 K Sum (2Sum, 3Sum, 4Sum)  算法优化(Optimization):  这里讲两点,第一,注意比如 3sum 的时候,先整体排一次序,然后枚举第三个数字的时候不需要重复,  比如排好序以后的数字是  a b c d e f,  那么第一次枚举 a,  在剩下的 b  c d e f 中进行 2  sum,  完了以后第二次枚举 b,
  只需要在  c d e f 中进行 2sum 好了,而不是在 a  c d e f 中进行 2sum,  这个大家可以自己体会一下,想通了还是挺有帮助的。  第二,K Sum 可以写一个递归程序很优雅的解决,具体大家可以自己试一试。写递归的时候注意不要重复排序就行了。 */
 List List Integer  ret = new ArrayList List Integer ();
 public List List Integer  threeSum(int[] num) { if (num == null || num.length   3) return ret;
 Arrays.sort(num);
 int len = num.length;
 for (int i = 0; i   len-2; i++) { if (i   0   num[i] == num[i-1]) continue;
 find(num, i+1, len-1, num[i]); // 寻找两个数与 num[i]的和为 0
 }
 return ret;
 }
 public void find(int[] num, int begin, int end, int target) {
 int l = begin, r = end;
 while (l   r) { if (num[l] + num[r] + target == 0) {
 List Integer  ans = new ArrayList Integer 
 ans.add(target);
 ans.add(num[l]);
 ans.add(num[r]);
 ret.add(ans); // 放入结果集中
 while (l   r   num[l] == num[l+1]) l++;
 while (l   r   num[r] == num[r-1]) r--;
 l++;
 r--;
 } else if (num[l] + num[r] + target   0) {
 l++;
 } else {
 r--;
 }
 }
 }
}

到此,相信大家对“Java 怎么求三个数是否为零”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计2405字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)