继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

算法入门之两数之和

码出一片_天
关注TA
已关注
手记 13
粉丝 6
获赞 27

题目描述

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

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

所以返回 [0, 1]

题目详解

这道题目给我们一个数组,数组里面全是整数,然后再给我们一个数字,需要我们求出在这个数组中哪两个数字的和正好是target。注意,你不能重复利用这个数组中同样的元素,指的是每一个位置上的数字只能被使用一次,比如数组 [3,3,5],你可以使用第一个和第二个 3,但是你不能使用第一个 3 两次。

解题方案

思路1: 时间复杂度: O(N^2) 空间复杂度: O(1)

暴力解法,双重循环遍历:

外层循环从数组中取出下标为 i 的元素 num[i],内层循环取出 i 之后的元素 nums[j] 一一与下标为 i 的元素进行相加操作,判断结果是否为 target。

下面我们来看代码

python beats27.6%

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        # 第一轮遍历
        for i in range(len(nums)):
            # 第二轮遍历不能重复计算了
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    # 注意 leetcode 中要求返回的是索引位置
                    return [i, j]

Java beats 36.03%

package com.company;

import java.util.HashMap;

public class sum {
    public static void main(String[] args) {
        int nums[] = {2,7,11,15};
        int target = 9;
        sum s = new sum();
        int twoIndex[] = new int[2];
        twoIndex = s.twoSum(nums,target);
        for(int a:twoIndex)
            System.out.println(a);
    }
        public int[] twoSum(int[] nums, int target) {
            HashMap<Integer, Integer> map = new HashMap<>();
            for (int i = 0; i < nums.length; i++) {
                // 将原本为两个目标值切换为一个目标值,只需要每次从 map 中寻找目标值即可
                int num = target - nums[i];
                if (map.containsKey(num)) {
                    return new int[]{map.get(num), i};
                }
                // 每次遍历过的值都存储到 map 中,这样之后就能从 map 中寻找需要的目标值
                map.put(nums[i], i);
            }
            return null;
        }
}

结果:2 3;

php

<?php
class Solution{
    public function two(){
        $nums = [2,7,11,15];
        $target = 26;
        for($i = 0;$i<count($nums);$i++) {
            for ($j = $i + 1; $j < count($nums); $j++) {
                if ($nums[$i] + $nums[$j] == $target) {
                    print_r([$i,$j]);
                }
            }
        }
    }
}
$res = new Solution();
$res->two();

结果:Array
(
[0] => 2
[1] => 3
)

可以看到上述代码的beats(代码优劣程度)明显较低,这是因为我们的时间复杂度是O(N^2)的。

思路2:时间复杂度: O(N) 空间复杂度: O(N)

上面的思路1时间复杂度太高了,是典型的加快时间的方法,这样做是不可取的。其实我们可以牺牲空间来换取时间。

java

package com.company;
import java.util.HashMap;
public class sum {
    public static void main(String[] args) {
        int nums[] = {2,7,11,15};
        int target = 9;
        sum s = new sum();
        int twoIndex[] = new int[2];
        twoIndex = s.twoSum(nums,target);
        for(int a:twoIndex)
            System.out.println(a);
    }
        public int[] twoSum(int[] nums, int target) {
            HashMap<Integer, Integer> map = new HashMap<>();
            for (int i = 0; i < nums.length; i++) {
                // 将原本为两个目标值切换为一个目标值,只需要每次从 map 中寻找目标值即可
                int num = target - nums[i];
                if (map.containsKey(num)) {
                    return new int[]{map.get(num), i};
                }
                // 每次遍历过的值都存储到 map 中,这样之后就能从 map 中寻找需要的目标值
                map.put(nums[i], i);
            }
            return null;
        }
}

php

<?php
class Solution{
    public function two(){
        $nums = [2,7,11,15];
        $target = 26;
        for($i=0;$i<count($nums);$i++){
            $num = $target - $nums[$i];
            if(in_array($num,$nums)){
                 echo $i.' ' ;
            }
        }
    }
}
$res = new Solution();
$res->two();
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP