今年的目标是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 未完待续。。