补一下之前刷的题

1.两数之和

给定一个整数数组 nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

示例 :

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

用哈希表解决问题

看见了一个很有趣的解法,原作者地址画解算法:1. 两数之和 - 两数之和 - 力扣(LeetCode) (leetcode-cn.com)

这道题本身如果通过暴力遍历的话也是很容易解决的,时间复杂度在 O(n2)
由于哈希查找的时间复杂度为 O(1),所以可以利用哈希容器 map 降低时间复杂度
遍历数组 nums,i 为当前下标,每个值都判断map中是否存在 target-nums[i] 的 key 值
如果存在则找到了两个值,如果不存在则将当前的 (nums[i],i) 存入 map 中,继续遍历直到找到为止
如果最终都没有结果则抛出异常

思路图解

初始化

13 - 2 = 11 ,map中不存在该key值,在map中存入(2,0)

13 - 7 = 5 ,map中不存在该key值,在map中存入(7,1)

13 - 11 = 2 ,该key值存在,返回2的下标0和11的下标2

代码实现

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i< nums.length; i++) {
            if(map.containsKey(target - nums[i])) {
                return new int[] {map.get(target-nums[i]),i};
            }
            map.put(nums[i], i);
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

7.整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围[-2^{31},2^{31}-1],就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

示例 :

输入:x = -123        输出:-321

输入:x = 120         输出:21

思路图解

拿到这个整数的 末尾数字 就可以了。
以12345为例,先拿到5,再拿到4,之后是3,2,1,我们按这样的顺序就可以反向拼接处一个数字了,也就能达到反转的效果。

怎么拿末尾数字呢?好办,用取模运算就可以了

  1. 将12345 % 10 得到5,之后将12345 / 10
  2. 将1234 % 10 得到4,再将1234 / 10
  3. 将123 % 10 得到3,再将123 / 10
  4. 将12 % 10 得到2,再将12 / 10
  5. 将1 % 10 得到1,再将1 / 10

这么看起来,一个循环就搞定了,循环的判断条件是x>0
但这样不对,因为忽略了负数
循环的判断条件应该是while(x!=0),无论正数还是负数,按照上面不断的 x/10 这样的操作,最后都会变成0,所以判断终止条件就是 x!=0

在Java中,负数取余,得到的余数也是负数

有了取模和除法操作,对于像12300这样的数字,也可以完美的解决掉了。

看起来这道题就这么解决了,但请注意,题目上还有这么一句

如果反转后整数超过 32 位的有符号整数的范围[-2^{31},2^{31}-1],就返回 0。

有些数字可能是合法范围内的数字,但是反转过来就超过范围了。
假设有1147483649这个数字,它是小于最大的32位整数2147483647的,但是将这个数字反转过来后就变成了9463847411,这就比最大的32位整数还要大了,所以肯定要返回0(溢出了)。

也就是说,我们不能直接用res与{\color{Red} 2^{31}}比较,得提前一位比较,在res还没取到第10位时,用9位的res与{\color{Red} 2^{31}}前九位比较

上图中,绿色的是最大10位整数
只要res的前九位 > 214748364 就溢出了,若 = 214748364,就再判断tmp是否 > 7

对于负数也是一样的

只要res的前九位 < -214748364 就溢出了,若 = -214748364,就再判断tmp是否 < -8

代码实现

class Solution {
    public int reverse(int x) {
        int res = 0;
        while(x!=0) {
            //每次取末尾数字
            int tmp = x%10;
            //判断是否 大于 最大32位整数
            if (res>214748364 || (res==214748364 && tmp>7)) {
                return 0;
            }
            //判断是否 小于 最小32位整数
            if (res<-214748364 || (res==-214748364 && tmp<-8)) {
                return 0;
            }
            res = res*10 + tmp;
            x /= 10;
        }
        return res;
    }
}			

9.回文数

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。

示例 1:

输入:x = 121
输出:true

示例 2:

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

方法1        转为字符串


class Solution {
    public boolean isPalindrome(int x) {
        String reversedStr = (new StringBuilder(x + "")).reverse().toString();
        return (x + "").equals(reversedStr);
    }
}

方法2        取后半段翻转

按照第7题回文数的思路,用如下代码段可以取出后半段并翻转

int revertedNumber = 0; 

//循环
int tmp = x % 10;
revertedNumber = revertedNumber * 10 + tmp;
x /= 10;

那么如何判断是不是回文数呢

判断 x 是不是小于 revertNum ,当它小于的时候,说明数字已经对半或者过半了

判断奇偶数情况:如果是偶数的话,revertNum 和 x 相等;如果是奇数的话,最中间的数字就在revertNum 的最低位上,将它除以 10 以后应该和 x 相等。

class Solution {
    public boolean isPalindrome(int x) {
        // 末尾为 0  直接返回 false
        if (x < 0 || (x % 10 == 0 && x != 0)) return false;
        int revertedNumber = 0;
        while (x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }
        return x == revertedNumber || x == revertedNumber / 10;
    }
}

13.罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符          数值
I                1
V               5
X              10
L               50
C              100
D              500
M              1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

思路图解

一言蔽之,把一个小值放在大值的左边,就是做减法,否则为加法

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值