LeetCode——01两数之和

今天正值清明节,在这离家几千公里的北京工作,祭祖啥的我看还是梦里想想就好了吧,在致敬英雄的同时,也不能忘了学习呀,好好学习为祖国做出更多的贡献才是对他们最大的致敬,上午到下午床上书桌上好好温习了一边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)));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值