前言

   感觉写博客是一个很耗心力的东西T_T,简单的写了似乎没什么用,复杂的三言两语也只能讲个大概,呸呸...怎么能有这些消极思想呢QAQ!那想来想去,先开一个leetcode的坑,虽然已经工作了,但是每天拿一两道题打发打发也不错嘛,不仅能锻炼思维,还能复习一些算法思想,又不怎么耗费时间撰写...还能骗博客数...,额好像又说了啥内心的真实想法:)...

Go

两数相加 Two Sum

  • Given an array of integers, return indices of the two numbers such that they add up to a specific target.

    You may assume that each input would have exactly one solution.

    Example:

    Given nums = [2, 7, 11, 15], target = 9,

    Because nums[0] + nums[1] = 2 + 7 = 9,

    return [0, 1].

  • 翻译: 两数之和

    给定一个整形数组和一个整数target,返回2个元素的下标,它们满足相加的和为target。

    你可以假定每个输入,都会恰好有一个满足条件的返回结果,也就是多种答案的情况不予考虑

    例如给定了数组 nums = [2, 7, 11, 15], 需要的target = 9,

    因为 nums[0] + nums[1] = 2 + 7 = 9,

    所以返回 [0, 1]


  • 思路一

    暴力解法,好吧程序员做久了人有时候容易变傻,就好像现在让你求从1加到100的和你想都不想for循环100次还说这是复杂度为O(n)哦,殊不知几百年前还在读小学的高斯就用求和公式O(1)时间就解决了T_T

    废话说完了,既然暴力解法这么傻,为啥还要讲,因为很多题目实在想不到解法时,可以先拟定一个暴力解法,然后再在这上面去优化时间与空间,寻找思路。

    最简单暴力解决就是多次遍历,两轮循环,把他们的和加起来,等于target就返回下标,如果啥都没就返回[-1,-1]
    public int[] twoSum01(int[] arr, int target) {

        if (arr == null) return new int[]{-1, -1};

        for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] + arr[j] == target) return new int[]{i, j};
}
} return new int[]{-1, -1};
}

核心代码就是中间的三行,很简单的两次遍历,数据量如果是在\(10^4\)这个范围内,\(O(n^2)\)级别的算法的时间在1秒内左右,所以如果数据量不是很大,这种暴力解法也是可以接受的。

  • 思路二

    \(O(n^2)\)的时间复杂度如果数据量很大自然是不能接受的,这里就从上面的暴力算法改进,在思路一中,每次遍历元素的时候都要把他和剩下的所有元素都比一遍,这真是太蠢了,你给一个小朋友做这道题他都不会这么解,那小朋友怎么解呢?

    假设数组内容是[2,7,11,15],目标值是17,那小朋友会先看2,17-2=15,那他就会去找有没有15,有15就把他们的位置给记下来,没有15就再看下一个数字。这里我们再把这种想法优化一下,程序化一下,代码如下
    public int[] twoSum(int[] nums, int target) {
if (nums == null) return new int[]{-1, -1};
Map<Integer, Integer> map = new HashMap<>();// 答案MAP,用于存储答案,key为数字,value为在数字集合中下标位置 for (int i = 0; i < nums.length; i++) {
Integer exceptNum = target - nums[i];//期望的答案
if (map.containsKey(exceptNum)) return new int[]{map.get(exceptNum), i}; //如果寻找到答案了,直接返回
else map.put(nums[i], i); //如果没有找到对应的答案,那么就把这个数本身作为答案放入答案map,根据a+b=b+a,正在遍历的数即是请求也是答案
}
return new int[]{-1, -1};
}

这里最初的思路就是拿空间换时间,最简单的处理是把所有的数组里的数都放到哈希表中,然后直接遍历get就可以了,但是这样未免太浪费空间,所以引入第二步优化思路,我需要多少,我就存多少元素,利用加法交换律a + b = b + a,正在遍历的元素同时就成为了备选答案存入map,这样比单纯的存入map中时间与空间的消耗期望值都是会少一些的。

总结

  题目很简单,算法题也有很多,但是思路其实并没有那么繁杂,合理利用这些思路,理解了一道题,这一类的题目就都理解了。

  • 在没有头绪的时候先尝试暴力解法,然后看看暴力解法里哪一步是可以优化的,例如本题中最外层循环肯定是不可避免的,但是内循环对于每一个数字都遍历所有就很没有必要,就可以在这点上作优化
  • 空间换时间,哈希表往往是最常用的选择之一,当然不仅仅是哈希表,树,堆,图,都是值得考虑的对象
  • 在使用空间换时间的优化中,充分利用已知的元素,最好能将已经遍历的过的元素存储再利用,这样往往能降低不少空间使用与时间消耗,虽然都是O(N)级别的空间,但是前面的常数系数明显是要小的。

leetCode in Java (一)的更多相关文章

  1. leetcode中Java关于Json处理的依赖

    leetcode的java代码提供的main函数中,往往有关于json的依赖...我找了许久才找到他们用的是这个json实现 <dependency> <groupId>com ...

  2. Binary Tree Preorder Traversal on LeetCode in Java

    二叉树的非递归前序遍历,大抵是很多人信手拈来.不屑一顾的题目罢.然而因为本人记性不好.基础太差的缘故,做这道题的时候居然自己琢磨出了一种解法,虽然谈不上创新,但简单一搜也未发现雷同,权且记录,希望于人 ...

  3. 290. Word Pattern【LeetCode by java】

    今天发现LintCode页面刷新不出来了,所以就转战LeetCode.还是像以前一样,做题顺序:难度从低到高,每天至少一题. Given a pattern and a string str, fin ...

  4. [leetcode]multiply-strings java代码

    题目: Given two numbers represented as strings, return multiplication of the numbers as a string. Note ...

  5. LeetCode二叉树Java模板

    public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } impor ...

  6. Leetcode Lect2 Java 中的 Interface

    什么是 Interface Java接口(Interface)是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以 ...

  7. leetcode(java)

    86 class Solution { public ListNode partition(ListNode head, int x) { ListNode lowheader=new ListNod ...

  8. 501. Find Mode in Binary Search Tree【LeetCode by java】

    Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred ...

  9. 7. Reverse Integer【Leetcode by java】

    Given a 32-bit signed integer, reverse digits of an integer. Example 1: Input: 123 Output: 321 Examp ...

随机推荐

  1. 浏览器F12进行Web程序调试

    转自http://www.cnblogs.com/yougewe/p/5152700.html 引语:如今的整个Web开发行业甚至说整个软件开发行业,已经相当成熟,基本上已经很少找不到没有前人做过的东 ...

  2. Python学习笔记4

    根据文件类型选择文件 文件 s s.split('.')[1] 即为文件后缀名,据此判断 输出执行后结果到指定文件 os.system('E:\\Learning\\python\\test_case ...

  3. hover用法实例

    //hover,鼠标移入移出的另一种用法 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" &qu ...

  4. CSS3学习手记

    --------------------CSS3新增选择器--------------------#E:nth-child(n):匹配元素类型为E且是父元素的第n个子元素#E:nth-last-chi ...

  5. new和newInstance区别

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp55     在初始化一个类,生成一个实例的时候:newInstance() ...

  6. C#构建DataTable(转)

    Asp.net DataTable添加列和行的方法 方法一: DataTable tblDatas = new DataTable("Datas"); DataColumn dc ...

  7. None是什么?

    None是什么,是空,就是空即是色,色即是空.是一个真的很特别的值,下面比较了下 0,True,False (python 的比較) >>> None == 0False>&g ...

  8. C# WinForm 跨线程访问控件

    问题出现: 在WinForm 处理多线程访问主线程的控件时候,就会出现如图所示的错误对话框:    解决方案:  方案一:去掉线程访问主线程UI控件的安全检查,使用: Control.CheckFor ...

  9. python re group()

    python group() 正则表达式中,group()用来提出分组截获的字符串,()用来分组 import re a = "123abc456" print re.search ...

  10. 关于SVM数学细节逻辑的个人理解(一)

    网上,书上有很多的关于SVM的资料,但是我觉得一些细节的地方并没有讲的太清楚,下面是我对SVM的整个数学原理的推导过程,其中我理解的地方力求每一步都是有理有据,希望和大家讨论分享. 首先说明,目前我的 ...