Leetcode 自学笔记

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


猜你喜欢

转载自blog.csdn.net/pcjdpcq/article/details/79687056
今日推荐