我的LeetCode学习笔记-1
来源:互联网 发布:curl 发送json数据 编辑:程序博客网 时间:2024/05/01 03:44
第一次接触到LeetCode,想通过LeetCode来提升自己的数据结构基础,以及算法能力。
也是第一次写博客,想着写好博客,以备自己复习,也是激励自己继续学习吧!
第一题,Two Sum 难度:简单
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,Because nums[0] + nums[1] = 2 + 7 = 9,return [0, 1].
原题如上,大意是给定一组整数,将两个数的返回指数相加,使它们相加成一个特定的目标。你可以假设每个输入都有一个解决方案,不能使用相同的元素两次。
第一念头肯定是通过遍历,也就是一开始学的冒泡法,一一比对,结果在官方给出的solution中,说这种方法属于Brute Force...蛮力(感觉也能提升自己的英语能力)。
solution2是two-pass Hash Table——两次遍历哈希表
public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { map.put(nums[i], i); } for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement) && map.get(complement) != i) { return new int[] { i, map.get(complement) }; } } throw new IllegalArgumentException("No two sum solution");}
从名字就很清晰明了的看出,通过HashMap存储,这里注意,key为数组中的值,value放位置,并且再遍历一次,通过containsKey来得到结果。
这里提一下containsKey的工作流程:
1. 调用 Map 的 get() 方法获取数据;
2. 如果返回不为 null, 直接返回该数据;
3. 如果返回为 null, 则生成数据, 或者从其他地方获取数据, 然后存放入 Map 中, 最后返回该数据.
在这里,target-nums[i]得到的comlement作为我们的索引,来查看map当中是否存在这个数据,若存在,则返回这个数值在数组中的位置,如果不存在,则返回null,并且这个索引得到的值,也就是在数组中的位置不能和当前位置相同,也就避免了重复,空间复杂度和时间复杂度都是蛮力解法的1/2次方,因为只需要遍历一次。solution3就是值得学习的办法了,one-pass Hash Table——一次遍历哈希表
public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[] { map.get(complement), i }; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution");}与上一个例子相比较就能得到非常清晰的逻辑,在为哈希表注入的时候,也同时回顾之前的值,此时也减少了判断重复的步骤。
也是这道题带给我最有用的启发(虽然之前学过,但是并不是每一次都能想起...)——在注入的同时,进行对之前数据的回顾。
第二题,Add Two Numbers 难度:中等
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)Output: 7 -> 0 -> 8Explanation: 342 + 465 = 807.
原题如上,大意是给出两个表示两个非负整数的非空链表。数字以相反的顺序存储,它们的每个节点都包含一个数字。添加两个
数字,并将其作为链接列表返回。你可以假设这两个数字不包含任何前导零,除了第0个数字本身。
这里说的“第0个数字本身”也就是头结点。在大一学习的以C语言为基础的数据结构当中,了解了“头结点”这个概念,但是头结点
的意义一直不是很懂,前段时间开始看Thinking in Java才有了一丝明悟,也就是Java中的堆栈,即栈中的变量指向堆内存中的变
量(这就是 Java 中的指针)。而在这道题中,充分理解了什么是Java指针以及头结点的作用。
首先给出Java中给单链表的定义
public class ListNode { int val; ListNode next; public ListNode(int x){ val=x; } }ListNode有两个属性,val作为存储值,next作为单链表中的单链。一开始我摸不着头脑,就算知道怎么存,但是怎么从ListNode
中把存入的值都取出来呢?因为单链表是无法后查前的,在这里我回想到了原来在C语言中使用过的双链表,不仅前查后,也可以通
过指针,用后面一个struct中查前边的指针来连接上一个struct,这里给了我灵感,何不设定一个头结点,将一个ListNode list连接到
该结点,再以这个list向下存值,最后以头结点得到list的位置。(其实全部都是大一的时候用过的,当时用链表写了一个存储各类数据
的超简陋的“数据库”,居然忘了,还是对头结点理解不够深刻,惭愧惭愧)
而对于数字相加的算法,对于我来说就属于简单了,判空,以及加一个辅助变量进行判断进位,so easy~
代码如下(方法用的官方solution,还是比自己写的更简洁,美观)
public static void main(String[] args) {ListNode dummyHead1 = new ListNode(0);ListNode dummyHead2 = new ListNode(0);ListNode l2 = dummyHead2;ListNode l1 = dummyHead1;l1.next = new ListNode(3);l1 = l1.next;l1.next = new ListNode(5);l1=l1.next;l1.next = new ListNode(4);l1= l1.next;l2.next = new ListNode(5);l2=l2.next;l2.next = new ListNode(6);l2=l2.next;l2.next = new ListNode(4);l2=l2.next;ListNode l3 = addTwoNumbers(dummyHead1.next, dummyHead2.next);System.out.println(l3.val+"->"+l3.next.val+"->"+l3.next.next.val);}public static ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode dummyHead = new ListNode(0); ListNode p = l1, q = l2, curr = dummyHead; int carry = 0; while (p != null || q != null) { int x = (p != null) ? p.val : 0; int y = (q != null) ? q.val : 0; int sum = carry + x + y; carry = sum / 10; curr.next = new ListNode(sum % 10); curr = curr.next; if (p != null) p = p.next; if (q != null) q = q.next; } if (carry > 0) { curr.next = new ListNode(carry); } return dummyHead.next;}最后得到3->5->4+5->6->4=8->1->9
突然想起自己备战NCRE的时候...明明都是自己会的,却想不起来了,真是惭愧*2
不过写博客的意义也在于此,激励自己继续学习,也以备回顾这些知识!!
加油!