我的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

  不过写博客的意义也在于此,激励自己继续学习,也以备回顾这些知识!!

  加油!





阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 三句情诗 浪漫情诗 伤感情诗 情诗情诗 五绝情诗 席慕蓉情诗 藏文情诗 普希金情诗 有名的情诗 唯美情诗 小情诗 相思情诗 著名情诗 问情诗 挽留情诗 好听的情诗 自创情诗 诗经情诗 分手情诗 寄情诗 普希金 情诗 四字情诗 古诗情诗 外国情诗 数学情诗 诗经 情诗 很美的情诗 相思的情诗 李白的情诗 古典情诗 优美的情诗 短情诗 怎么写情诗 唐宋情诗 感人情诗 表白的情诗 著名的情诗 情诗古诗 情诗宋词 情诗朗诵 情诗现代诗