今天正值清明节,在这离家几千公里的北京工作,祭祖啥的我看还是梦里想想就好了吧,在致敬英雄的同时,也不能忘了学习呀,好好学习为祖国做出更多的贡献才是对他们最大的致敬,上午到下午床上书桌上好好温习了一边zookeeper的相关知识,然后还上最大的同性交友网站git上拉了他的源码小撸了下,然后觉得有些无聊,偶然发现好久没刷leetcode的题了,发现之前做过的题都有点陌生了,然后有个小计划,以后每周按顺序每周整个3-10题,然后我会把相关题解发到这里,先申明下呀,题解是自己写的,可能会有bug,但我会在上面过了才发,仅供参考。
今天入手的第一题,很简单的一道题,就没废话了,我直接放代码吧,可能这里更多的也是放代码,代码里有写重要的地方做了注释,如有不明白欢迎骚扰。
package club.mossflower.leetcode;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ____/`---'\____
* .' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* 佛祖保佑 永无BUG
* @ProjectName: mossflower
* @Package: club.mossflower.leetcode
* @ClassName: TowNumSun
* @Author: liugenkun
* @Description:
* 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
* 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
* 示例:
* 给定 nums = [2, 7, 11, 15], target = 9
* 因为 nums[0] + nums[1] = 2 + 7 = 9
* 所以返回 [0, 1]
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/two-sum
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
* @Date: 2020/4/4 20:17
* @Version: 1.0
*/
public class Solution {
/**
* 暴力法
* 一看题目两数,还好知道路的尽头,用最简单的头脑想,
* 一共两个数,无非是先固定一个,然后在寻找另外一个满足要求的
* 下面给出这种暴力求解法的具体实现
* 分析代码时间复杂度不用多说:O(n^2)
*/
public static int[] twoSum_BL(int[] nums, int target) {
for (int i = 0; i < nums.length-1; i++) {
for (int j = i+1; j < nums.length; j++) {
if (nums[i]+nums[j] == target){
return new int[]{i,j} ;
}
}
}
return new int[]{};
}
/**
* 双指针
* 上面的方法虽然能找到答案,但是好像时间复杂度过不了,下面分析另外一种方法;
* 假如我们给出的数据是有序的:a<b<c,目标值 t
* 现有a+c<t,那么我们还会去算a+b吗 肯定我们不会去算了吧 因为b<c,所以我们只要去算b+c就好了
* 依次思路,我们可以避免很多的重复计算,以达到提高效率的目的
* 此方法在这题中可能并没什么效率可言,但这是一种思考方式,这里主要性能浪费在了排序上,排序我用了一个冒泡,性能可想而知
* 如果其他处理性能远大于排序时该方法效果就可以体现出来
*/
public static int[] twoSum_DZ(int[] nums, int target) {
//为了找到原来的位置做返回,先要保存原来地位置
int[] idx = new int[nums.length];
for (int i = 0; i < nums.length ; i++) {
idx[i] = i;
}
//排序
for (int i = 0; i < nums.length-1 ; i++) {
for (int j = i+1; j < nums.length ; j++) {
if (nums[j]<nums[i]){
//后面的小于前面的需要交换位置
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
//对应的指针也要交换
int idx_t = idx[i];
idx[i] = idx[j];
idx[j] = idx_t;
}
}
}
int right = nums.length-1;
int left = 0;
while (left<right){
if (nums[right] + nums[left] == target){
//满足要求的值,返回
return new int[]{idx[left],idx[right]};
}
if (nums[right] + nums[left] >target){
//大了找小的
right--;
}
if (nums[right] + nums[left] < target){
left++;
}
}
return new int[]{};
}
/**
* 基于缓存
* 当我们确定一个数时,要想满足条件,必定有另一个确定的值对应
* 实现如下
*/
public static int[] twoSum_CH(int[] nums, int target) {
//用于缓存数据
Map<Integer,Integer> temp = new HashMap<>(nums.length);
for (int i = 0; i < nums.length; i++) {
//确定当前数
int num = nums[i];
//如果存在另一个值必为
int exp = target - num;
//查看有没期望得到的值
Integer integer = temp.get(exp);
if ( integer != null){
return new int[]{i,integer};
}
temp.put(num,i);
}
return new int[]{};
}
public static void main(String[] args) {
int[] nums = new int[]{5,8,16,3,2,15,31};
int target = 18;
System.out.println(Arrays.toString(twoSum_CH(nums,target)));
}
}