今年的目标是LeetCode 150道题刷两遍,趁着这个机会把学习思路记录下来,以便之后的回顾
第1题 难度 easy
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].
思路如下
两次遍历同一个数组,索引分别是 i,j 其中j=i+1,计算两个数值相加是否等于目标值,如果等于则将索引存入一个新的数组中,并返回结果。
复杂度 N!
class Solution { public int[] twoSum(int[] nums, int target) { int result[]; result=new int[2]; for (int i=0;i<=nums.length;i++){ for(int j=i+1;j<nums.length;j++){ if (nums[i]+nums[j]==target){ result[0]=i; result[1]=j; break; } } } return result; } }
第2题 难度 medium
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 -> 8 Explanation: 342 + 465 = 807.
思路
创建一个新的链表来承接结果, 创建两个int型 来进行计算。
temp 用来计算两数相加之和,carry 来承接两个数字相加的10位数。(如果temp <10 则carry 等于0 否则等于1)
用while 来遍历输入的两个链表,如果两个链表不为空 或者carry 大于0 则进行循环
这道题在面试中实际遇到过,没有答得太好。
从别人那边copy出来的结果,思路和我的差不多 但是 比我考虑的周到,我没有考虑到 链表都为空的时候,其次就是 链表的声明啥的都搞不明白 希望下次 再刷的时候 能够 比这次更加高效一些
class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode result, node; int temp, carry = 0; if (l1 == null && l2 == null) { return null; } result = new ListNode(0); node = result; while (l1 != null || l2 != null || carry > 0){ temp = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val) + carry; carry = temp < 10 ? 0 : 1; node.next = new ListNode(temp % 10); node = node.next; if (l1 != null) l1 = l1.next; if (l2 != null) l2 = l2.next; } return result.next; } }
第7题 难度easy
Given a 32-bit signed integer, reverse digits of an integer.
给定一个32位带符号整数,返回一个整数的反向数字。
反向溢出时 返回0
Example 1:
Input: 123 Output: 321
Example 2:
Input: -123 Output: -321
Example 3:
Input: 120 Output: 21
这道题我没有考虑到如果溢出了该如何处理。如1234567899 反向 就是9987654321 超过integer 的最大值 2^32 (2147483647)了.
思路如下
记录正负号,如果x>0则flag=1否则=-1
之后去x的绝对值进行计算。
如果a(x的绝对值)>0则进入循环,ret 取a的最后一位数并将自己乘以10.
这样如果a仍然大于0 并且ret 大于integer的十分之一 则证明 a的反向数字将大于integer的最大值,此时返回0。
如果a不在大于0了,返回结果并且加上符号,作为返回值。
这个solution 取自 同事,虽然我的思路和他的差不多 不过实际的代码量跟这个十多年经验的同事相比差很多,还是需要学习。
class Solution { public int reverse(int x) { int flag = x>0?1:-1; int ret=0; int a=Math.abs(x); while (a>0){ if(ret>Integer.MAX_VALUE/10){ return 0; } ret=ret*10+a%10; a=a/10; } return ret*flag; }
第9题 难度easy
回文数,就是正反看都一样 如汉语的 画上荷花和尚画 类似 正着读和倒着读都一样。
需要设计算法判断一个integer是否是回文数 类似 123321的数值, 负数不符合回文数
我的思路打算用递归函数结果这个直接用循环就好了。我的思路总是考虑不到多种情况。
下面介绍一下经过同事点拨后的算法
比较input值的首尾是否相等,如果相等则去掉首尾在进行比较
x=(x-x/base*base)/10; // 一步去掉首尾
这一步计算容易看乱, 其中优先计算的事x/base (base 是x的位数 如x=1234 则 base就是1000) 这一步求出来 x的首位 注意这里是integer 的除法 只求出整数,例如这里如果 x是1234的话
第一步就是 1234/1000 = 1
第二步 1*1000 =1000
第三步 1234-1000= 234
第四步 234/10 = 23
因此这一行 相当于 进行了这四步计算,我这个同事妙啊!
其他的步骤都有注释 大家可以自行查看
class Solution { public static boolean isPalindrome(int x) { if(x<0) return false; if(x==0) return true; int base=1; while(x/base>=10){ // 求出base 的值 base 就是 x的最大位数(个十百千那个) base*=10; } int end=x%10; int start=x/base; while(start==end){ x=(x-x/base*base)/10; // 一步去掉首尾 base=base/100; // 因为x 被去掉首尾 base 需要减少2位 if(x==0) //x==0证明首尾都取完了 break; end=x%10; //取尾 start=x/base; //取首 } if(x>0) //大于0 证明有问题 所以false 如 10021 最后剩下 2 return false; else return true; //只有等于0的时候是 true } }更新自 2018-03-25 未完待续。。