百题突破,余烬犹存
被同学带着去刷算法,一晃两个月,突破了一百题了,期间经历过数据结构、贪心、动态规划、二分查找等等类型的题目,还有少数的智力题,在此过程中感觉获益良多,特此写一篇总结。
是什么,可以摆脱无聊的环境问题,不被语言、硬件所限制?--算法
是什么,是隐藏在万物之中的规律?--算法
是什么,只存在逻辑与计算,脱离繁琐的业务?--算法
平台选用了leetcode,题目的水平属于ACM入门级(尽管这样还是难。。),题目有easy,medium,hard三档,再开始刷题大概半个月之后,我强迫自己不刷easy了。easy大多都是埋坑的题目,思维难度不大,细节多。直到最近,强迫自己刷多点hard的题目。在此篇中,我就自己做过的题目归类分为:数据结构类、分治类、动态规划类、贪心类、回溯类等五类。
算法只能锻炼程序员的思维,不能帮程序员提升业务能力,但是他是个很有意思的玩意。
一.热身篇
要做这件事(刷题),首先对某门语言进行熟悉,只需要熟悉逻辑结构的语法就行了;接下来就是先从简单的开始(每个人的简单不一样),寻找正反馈;然后逐步提升难度、限时、加量。
什么样的题目比较适合热身的?就是基于你现在的水平一眼就能看到逻辑的,最好能在脑里模拟程序运行步骤的,并且分析它的时间空间复杂度。
来吧,我们一起水题。
先看第一题,是不是特别简单一眼就看出来了。它需要寻找两个数加起来等于target的,并且把位置返回。直观的想到使用两个变量,双重循环做加法匹配。
类似这样一次遍历,它的平均复杂度是O(n^2),空间复杂度O(1)
class Solution { public int[] twoSum(int[] nums, int target) { for(int i=0;i<nums.length;i++){ for(int j=0;j<i;j++){ if(nums[i]+nums[j] == target){ return new int[]{j,i}; } } } throw new IllegalStateException("there is no return"); } }
如果针对这个算法做优化,可以做成O(n)时间复杂度,但是要付出另外O(n)的空间
public class TwoSum { public void test(){ int[] nums = {3,2,4}; int[] result = twoSum(nums,6); for(int v : result){ System.out.println(v); } } public int[] twoSum(int[] nums, int target) { Map<Integer,Integer> indexMap = new HashMap<>(); for(int i=0;i<nums.length;i++){ int temp = target - nums[i]; if(indexMap.containsKey(temp)){ return new int[]{indexMap.get(temp),i}; } indexMap.put(nums[i],i); } throw new IllegalStateException("there is no return"); } }
使用HashMap可以使得查询效率变为O(1),这样写就是几乎最快的解法了。
还有很多类似的题目热身,就不再赘述了。
二.数据结构篇
https://www.cnblogs.com/chentingk/p/11655834.html
三.动态规划篇
https://www.cnblogs.com/chentingk/p/11608380.html
四.贪心法篇
https://www.cnblogs.com/chentingk/p/11691755.html
五.回溯篇
https://www.cnblogs.com/chentingk/p/11697506.html