Design and implement a TwoSum class. It should support the following operations: add and find.

add - Add the number to an internal data structure.
find - Find if there exists any pair of numbers which sum is equal to the value.

这个解法很容易想到,但很容易超时。

基本来说有这样几个途径去解。

第一种,使用一个数组去存所有加入的元素,使用一个Set去存所有的和。在实现Find的时候,遍历数组,把能够得到的和都加到set中去。这样,find的时间复杂度是O(1)了,因为只需要判断value是否在集合里面,但是add就变成了O(n)。实践证明这是行不通的。

第二种,还是使用一个数组去存元素,但是每次加入的时候保持数组有序,这样虽然可以通过二分查找找到插入点,但是插入本身,由于是在数组中,复杂度就变成O(n)了。在实现Find的时候,使用TwoSum标准算法(用两个指针,一前一后遍历)。所以这个也没有好多少,还是会超时。

第三种,不要使用数组了。使用一个Search Tree来存放元素。这样在add的时候可以基本保证O(logn)。

Find怎么办呢?

其实也可以采用TwoSum的那个标准算法,但是需要在TreeNode里面存放一个pre和next指针,分别是排序后的,该节点的前一个和后一个元素。这样你远看是一颗树,近看是双向链表。

在二叉排序树中插入一个节点大家都会,要注意的是如何在插入的过程中,记录pre和next。其实只要是向右搜索,我们就给pre赋值,向左搜索就给next赋值就可以了。

哦,对了,还要在插入过程中注意update 双向链表的head和tail,这个也很容易,只要插入后发现pre是null,那么这个节点肯定是head嘛,next是null就是tail咯。

代码是这个。

public class TwoSumDS {

    private TreeNode root;
private TreeNode head;
private TreeNode tail; //private Set<Integer> seenSum = new HashSet<>(); public void add(int number) {
if (root == null) {
root = new TreeNode(number);
head = tail = root;
} else {
insertIntoTree(number);
}
} public boolean find(int value) {
{
if (head != null && tail != null && head != tail) {
TreeNode p = head, q = tail;
while (p != q) {
int sum = p.val + q.val;
//seenSum.add(sum);
if (sum > value) {
q = q.pre;
} else if (sum < value) {
p = p.next;
} else {
return true;
}
}
}
}
return false;
} private void insertIntoTree(int val) {
TreeNode p = root;
TreeNode pre = null;
TreeNode next = null;
while (true) {
//seenSum.add(val + p.val);
if (val > p.val) {
pre = p;
if (p.right != null) {
p = p.right;
} else {
p.right = new TreeNode(val);
insertInToChain(p.right, pre, next);
break;
}
} else {
next = p;
if (p.left != null) {
p = p.left;
} else {
p.left = new TreeNode(val);
insertInToChain(p.left, pre, next);
break;
}
}
}
} private void insertInToChain(TreeNode n, TreeNode pre, TreeNode next) {
if (pre != null) {
pre.next = n;
} else {
head = n;
}
if (next != null) {
next.pre = n;
} else {
tail = n;
}
n.pre = pre;
n.next = next;
} private static class TreeNode {
int val;
TreeNode right;
TreeNode left;
TreeNode pre;
TreeNode next;
TreeNode(int val) {
this.val = val;
}
} public static void main(String[] args) {
TwoSumDS ts = new TwoSumDS();
ts.add(1);
ts.add(3);
ts.add(5);
System.out.println(ts.find(4));
System.out.println(ts.find(7));
}
}

注意到撸主注释的部分,有一个优化。就是在插入和搜索过程中,沿途找到的sum我们缓存起来,下次说不定可以用。Find的之前可以先在seenset里面看看。

不过这个优化导致了超时,所以就去掉了。看了一下Java doc,并没有gurantee HashSet的存放操作是O(1)的。

看来Java还没有很多人提交哟:>

LeetCode 笔记27 Two Sum III - Data structure design的更多相关文章

  1. 【LeetCode】170. Two Sum III – Data structure design

    Difficulty:easy  More:[目录]LeetCode Java实现 Description Design and implement a TwoSum class. It should ...

  2. 【leetcode】170. Two Sum III - Data structure design 两数之和之三 - 数据结构设计

    Design and implement a TwoSum class. It should support the following operations:  add and find. add  ...

  3. 【LeetCode】170. Two Sum III - Data structure design 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数组+字典 平衡查找树+双指针 日期 题目地址:htt ...

  4. 170. Two Sum III - Data structure design【easy】

    170. Two Sum III - Data structure design[easy] Design and implement a TwoSum class. It should suppor ...

  5. [LeetCode] Two Sum III - Data structure design 两数之和之三 - 数据结构设计

    Design and implement a TwoSum class. It should support the following operations:add and find. add - ...

  6. LeetCode Two Sum III - Data structure design

    原题链接在这里:https://leetcode.com/problems/two-sum-iii-data-structure-design/ 题目: Design and implement a ...

  7. LeetCode 170. Two Sum III - Data structure design (两数之和之三 - 数据结构设计)$

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

  8. [LeetCode] 170. Two Sum III - Data structure design 两数之和之三 - 数据结构设计

    Design and implement a TwoSum class. It should support the following operations:add and find. add - ...

  9. ✡ leetcode 170. Two Sum III - Data structure design 设计two sum模式 --------- java

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

随机推荐

  1. android基础开发之scrollview

    scrollView 是android系统提供的一种 特殊的展示view. 其实我们很早就遇到过scrollview的东东,比如listview. 而google官方文档也提出,不要混合使用scrol ...

  2. nginx安装过程,报错处理:make[1]: *** [objs/addon/src/bson.o] Error 1

    nginx安装过程中,经常会有各种错误: 具体安装步骤这里不做说明,网上一搜大把: 主要分析安装过程中遇到的问题 在make编译的时候,若报如下错误: cc1: warnings being trea ...

  3. Centos7安装配置gitlab

    Centos7安装配置gitlab 这篇文字我会介绍在Centos7上安装gitlab,配置gitlab的smtp,并且创建项目demo. sudo yum install openssh-serve ...

  4. Effective Java 14 In public classes, use accessor methods, not public fields

    Principle To offer the benefits of encapsulation you should always expose private field with public ...

  5. 测试mysql的sql语句预编译效果

    玩Oracle的都比较关注shared pool,特别是library cache,在使用了绑定变量(预编译sql)之后确实能得到很大的性能提升.现在在转Mysql之后特别是innodb很多东西都还能 ...

  6. xml in hadoop ETL with pig summary

    项目中需要把source为xml的文件通过flume放置到hdfs,然后通过MR导入到vertica中去,我之前做过简单的 尝试,是通过pig的piggybank的xmlloader然后Regex_e ...

  7. Hadoop 2.0 中的资源管理框架 - YARN(Yet Another Resource Negotiator)

    1. Hadoop 2.0 中的资源管理 http://dongxicheng.org/mapreduce-nextgen/hadoop-1-and-2-resource-manage/ Hadoop ...

  8. Web安全--XSS现代WAF规则探测及绕过技术

    XSS现代WAF规则探测及绕过技术初始测试 1.使用无害的payload,类似<b>,<i>,<u>观察响应,判断应用程序是否被HTML编码,是否标签被过滤,是否过 ...

  9. 【MVC 4】1.第一个 MVC 应用程序

    作者:[美]Adam Freeman      来源:<精通ASP.NET MVC 4> ASP.NET MVC 是微软的一个 Web开发框架,它整合了“模型—视图—控制器(MVC)”架构 ...

  10. 【Android UI设计与开发】6.底部菜单栏(三)使用Fragment+PopupWindow仿QQ空间最新版底部菜单栏

    直接看栗子吧,效果基本实现,界面微调和弹窗的优化,去做的话会很耗时说,暂时就酱紫了.上传效果动态图太大了,直接手机截图的效果图如下: 至于代码的实现主要就是自定义的菜单栏,和用 PopupWindow ...