1.1 Leetcode 练习——两数之和 第一题 使用Java语言

Leetcode 练习 1.1

两数之和 第一题

题目:

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]

提示:

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案


以下是以相关解答,暂不要求多种方法

使用 Java 语言:

public int[] twoSum(int[] nums, int target) {
// 以上是leetcode 上所给的格式
    int[] res = new int[2];
    if(nums == null || nums.length == 0){
        return res;
    }
    Map<Integer, Integer> map = new HashMap<>();
    for(int i = 0; i < nums.length; i++){
        int temp = target - nums[i];
        if(map.containsKey(temp)){
            res[1] = i;
            res[0] = map.get(temp);
        }
        map.put(nums[i], i);
    }
    return res;
}

代码执行结果:
使用Java语言后的代码执行结果


关于Java代码进行分析:


1号代码块:
int[] res=new int[2];
  • 这是对数组的声明和初始化
    [ ] 里面的2 代表的是数组的大小,即里面可以装载2 个元素(这里是整型数组,所以里面就可以装载 2 个整数);
  • 以下是C++中的理解:
    new int[ ] 是创建一个 int 型数组 ,数组大小是在 [ ] 中指定的,
    例如: int *p =new int [3] ; ----这是申请一个动态整型数组,数组的长度为 [ ] 中的值
    new int( ) 是创建一个 int 型数 ,并且用 () 括号中的数据进行初始化
    例如: int *p = new int(10); ----p指向一个值为 10 的int数。


2号代码块:
 if(nums==null || nums.length==0){    
        // 如果nums是null就不会再判断后面的语句

int[ ] nums; // 声明
// 不能打印 nums 的值

int[ ] nums = null;
/* 声明,栈中 nums 存的是 null ,不指向堆空间的对象,没有指针
栈中 nums 存的是 null ,不指向堆空间的对象,没有指针。 nums.length 会出现空指针异常*/

int[ ] nums = new int[0];
/* 声明,在堆中创建了一个对象,栈中 nums 指向了堆,堆中为数组创建了一个 0 的空间
在堆中创建了一个对象,栈中 nums 指向了堆,堆中为数组创建了一个 0 的空间。nums.length 为 0 。(new 就表示,创建了一个指针指向堆,即栈中存了堆空间的地址,即创建了一个对象) */

所以在一个方法中,形参是一个数组时,最好先判断是否为空、长度是否为0,且有先后顺序。
如果先判断长度是否为 0 ,若数组是 null 会出现空指针异常。就是说,关于“ nums==null || nums.length ==0 ”这个顺序最好不要颠倒

//  同理,二位数组
if(nums == null) || nums.length == 0 || nums[0].length ==0 ) {}     
// 如果是null,就不会再判断后面的语句

所以在一个方法中,要返回一个没有结果的数组,最好返回一个长度为 0 的数组,而不是 null 。 因为是null的话,还需要进行 if(nums == null) 的检查。

// 最好返回一个长度为 0 的数组
return new int[0]


3号代码块:
Map<Integer,Integer> map=new HashMap<>();

Map map = new HashMap();

定义泛型:
在这里插入图片描述
Map “key-value” 键值对接口, HashMap是它的实现类
这里其实Map是你自己定义的一个接口,你调用这个接口来实现你要完成的动作,这样别人直接用你这个接口就可以了,而不用关心你具体是怎么实现这个接口的,假如以后有变动的话,你也不用再去管这个接口,只需要改你的实现类就行了,方便维护,隔离性强。
放值:m1.put(1,“one”);
取值:m1.get(1);

HashMap

HashMap 继承于 AbstractMap 类,实现了 Map 接口。
HashMap 就是一个散列表,它是通过“拉链法”解决哈希冲突。(哈希冲突:当我们对某个元素进行哈希运算,得到一个存储地址,然后要进行插入的时候,发现已经被其他元素占用了)也就是数组+链表的方式

HashMap map = new HashMap();

而这个,你所定义的就是一个实现类,你把这个实现类给别人用,如果出现问题和改动的话,那么程序就无法运行,凡是用到这个类的地方都要修改,维护起来很麻烦。而上面的接口,你只要改你实现这个接口的实现类就可以了。以此来降低耦合性。

使用 Map 的好处就是 new 后面可以跟其他的实现,不一定是HashMap 可以跟其他的,如果用HashMap 声明的话,new 后面貌似就只能跟HashMap了。



4号代码块:
for(int i=0; i< nums.length; i++){ }

对于数组:length 是属性, nums.length 表示数组的长度
对于字符串:length( ) 是方法,通过 nums.length( )来获取字符串的长度

i ++ 和 ++i 的区别:

  1. i++ 先赋值后加,即返回原来的值, ++i 先加后赋值,即返回加1后的值
  2. i++ 不能作为左值,而 ++i 可以

关于左值:

  • 左值是对应内存中有确定存储地址的对象的表达式的值,而右值是所有不是左值的表达式的值。
  • 一般来说,左值是可以放到赋值符号左边的变量。但能否被赋值不是区分左值与右值的依据。
  • 比如,C++的 const 左值是不可赋值的;而作为临时对象的右值可能允许被赋值。
  • 左值与右值的根本区别在于是否允许取地址& 元素安抚获得对应的内存地址。


5号代码块:
 for(int i=0; i< nums.length; i++){
 //使用for循环,给整型变量i赋初值为0,当i取值小于数组nums的长度时,进行i++操作
            int temp=target -nums[i];
            //num[i]即为数组中的第i+1个元素
            //将变量target减去num[i]中的值 赋值给整型变量 temp
            
            if(map.containsKey(temp)){     //判断是否包含指定的键值
            //Java 集合类中的 Map.containsKey( ) 方法判断 Map 集合对象中是否包含指定的键名。如果 Map 集合中包含指定的键名,则返回true,否则返回 false
            //相关的语法是: containsKey(Object key)
            //参数说明:  key 是要查询的 Map 集合的键名对象,就如上面代码中的temp
            
            // 如果条件为真:
                res[1]=i;      //将i的值赋值给数组res中的第二个元素 
                 
                res[0]=map.get(temp);     // 使用get 方法获取指定键 temp 中所映射的值,然后将值赋值给数组res中的第一个元素
                //Java集合类中的Map.get( )方法返回指定键所映射的值。如果此映射不包含该键的映射关系,则返回null
                // 语法:  get(Object key)
                // 参数说明: key 是指定的 Map 集合中的键名
               
            }
            // 如果条件为假:
            map.put(nums[i],i);    //如果调用 key(num[i])找不到对应的 value(i),则返回null
            
            // put( ) 函数语法: V put(K key,V value)
            // 使用的参数:该方法有两个参数。key:与指定值相关联的键; value:与指定键关联的值。
            //返回值:当存在这个key的时候,会覆盖掉原来的value并返回oldvalue,也就是旧值。
            /*
            对于返回值的进一步解释:
            **1.如果没有键映射,则返回NULL;
            **2.该函数返回与指定键关联的旧值;
            **3.这个操作不管啥条件都会覆盖旧的
            */
        }
        return res;

Java循环中的for语句:

  • java 语言的 for 循环语句是一个循环控制结构,可以执行指定次数的循环
  • Java 语言提供了三种循环结构,还有 while 和 do … while
  • for 循环执行的次数是在执行前就确定的

for 语句中的语法:
for( 初始化;布尔表达式;更新 ) { /* 代码语句*/ }

  1. 最先执行初始化步骤,可以声明一种类型,但可以初始化一个或多个循环控制变量,也可以是空语句
  2. 然后,检查布尔表达式的值
    如果为 true ,循环体被执行
    如果为 false ,循环终止,开始执行循环题后面的语句
  3. 执行一次循环后,更新循环控制变量
  4. 再次检测布尔表达式,循环执行上面的过程

Java 增强 for 循环
Java 中还有一种主要用于数组的增强型 for 循环
Java 增强 for 循环 语法格式 如下:
for (声明语句 : 表达式 ){ /* 代码语句 */}

  1. 声明语句 声明新的局部变量,该变量的类型必须和数组元素的类型匹配
    其作用域限定在循环语句块,其值与此时数组元素的值相等
    2.表达式 是要访问的数组名,或者是返回值为数组的方法

PS:以上为本人的学习笔记,主要目的是想通过做题来将知识点来进行回顾整合,本人学渣,如有不对的地方,敬请赐教,欢迎在评论区下留言指正 ^ _ ^

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值