算法题 week1

leetcode

1#  两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]

思路:最先想到的是双层循环遍历,计算每两个数的和与target的关系,如果相等,返回两个数的下标,如果没有满足条件的值,则抛出异常。

双层遍历循环

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] arr=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){ 
                    arr[0]=i;
                    arr[1]=j;
                    return arr;
                }
            }
        }
    throw new IllegalArgumentException("No two sum solution");
    }
}

由于是双层循环遍历,时间复杂度较高,是O(n^2),开辟了一个长度为2的数组,空间复杂度O(1)

 题解中在返回下标时按如下方式书写,更简洁

 return new int[] { i, j };

 7#  整数反转  

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:输入: 123输出: 321 示例 2:输入: -123输出: -321示例 3:输入: 120输出: 21

注意:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31,  2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

思路:利用栈的思想对数字进行翻转,溢出判断以反转后的结果为依据进行判断;每次取一位,在不断迭代中实现反转。

class Solution {
    public int reverse(int x) {
        int temp = 0;
    while(x!=0){
        int pop = x%10;//保存末位数
        x = x/10;//截断末位数
        //溢出判断
        if(temp>Integer.MAX_VALUE/10||(temp==Integer.MAX_VALUE&&pop>7)) return 0;
        if(temp<Integer.MIN_VALUE/10||(temp==Integer.MIN_VALUE&&pop<-8)) return 0;
        temp = temp*10+pop;
        
    }      
       return temp; 
    }
}

9#  回文数

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1:

输入: 121
输出: true
示例 2:

输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:

输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。

 思路:回文数是对称的,且为正数,用上题的方法将数字翻转,如果相等,即为回文数。

class Solution {
    public boolean isPalindrome(int x) {
        int ref = 0;
        int a =x;
        if(x<0||(x%10==0&&x!=0))  
            return false;
        while(x>0){
            int pop = x%10;
            x = x/10;
            ref = ref*10+pop;
        }
       return ref==a;
        
    }
}

题解考虑到反转溢出的问题(评论说回文数不可能溢出),将数字反转一半,当原数字小于反转后的数字时,跳出循环。

public class Solution {
    public bool IsPalindrome(int x) {
        // 特殊情况:
        // 如上所述,当 x < 0 时,x 不是回文数。
        // 同样地,如果数字的最后一位是 0,为了使该数字为回文,
        // 则其第一位数字也应该是 0
        // 只有 0 满足这一属性
        if(x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int revertedNumber = 0;
        while(x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }

        // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
        // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
        // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
        return x == revertedNumber || x == revertedNumber/10;
    }
}

 

posted @ 2019-09-09 17:19  小新要变成学霸  阅读(158)  评论(0编辑  收藏  举报