剑指Offer 11. 旋转数组的最小数字
解答1[Java]:
1 | public class Solution { |
时间复杂度
时间复杂度为对数级别 $O(logN)$。
解答2[Java]:时间复杂度 $O(n/2)$
1 | public class Solution { |
思路
旋转之后,从左向右对比两个相邻的数,总会找到一组数,第一个数大于第二个数,那么第二个数就是最小值。因为第二个数往后的所有数就是旋转操作移到最后的一系列数。
1 | public class Solution { |
时间复杂度为对数级别 $O(logN)$。
1 | public class Solution { |
旋转之后,从左向右对比两个相邻的数,总会找到一组数,第一个数大于第二个数,那么第二个数就是最小值。因为第二个数往后的所有数就是旋转操作移到最后的一系列数。
关于二进制的表示方法,需要深入的了解一下。这个内容和Java中整形变量的存储有关。
整形类型,以二进制表示的情况下,最高位是符号位,其余用来存储具体数值。符号位为0,那么是一个正值,符号位为1,那么为一个负值。那么是不是对于一个正值,十进制下值为5,是不是把二进制表示情况下的最高位从0改为1,这个值就变成-5了呢?
其实不是的。二进制表示的正数和负数,计数规则是不一样的。
今天计算机当中表示整数最普遍的系统是二进制补码(two’s complement)计数法。
我们来看使用4个位(bit)来表示整数的情况。
第一位是符号位,表示正负,0 代表为正,1代表负。
剩下三位,表示正数的时候就和普通的二进制计数法一样。
表示负数的时候,000表示8,001表示7……
如图所示:
如何把表示负数的补码转换成普通的二进制表示法呢?
首先,根据符号位确定正负号,然后把符号为排除在外。
然后把补码从右向左数,遇到第一个1之后,把第一个1左边的所有数取反,也就是0改为1,1改为0。
然后再按照普通二进制计数法来解读就可以了。
比如 1001
表示 -7
实际就是,先把符号为看作负号,然后把 001
中 1
左边的 00
改为 11
,最后结果就是 -7
。
题目来源:https://leetcode.com/problems/multiply-strings/
题目难度:Medium
1 | import java.util.Scanner; |
这个算法基于一下规律:
i
和 j
的两个数相乘,乘积的位数不超过 i+j
位。i+j
的数组,那么第一个数的第 i
位和第二个数的第 j
位的乘积会影响结果的第 i+j
位和第 i+j+1
位。因此,把第一个数的第 i
位和第二个数的第 j
位的乘积先存到结果的 i+j+1
位,最后再统一计算进位。
1 | import java.util.Scanner; |