1. 位运算
Leetcode 191. Number of 1 Bits 二进制中1的个数(剑指offer10题)
Write a function that takes an unsigned integer and returns thenumber of ’1' bits it has (also known as the Hammingweight).
For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011
, so the function should return 3
不能使用让原始数n不断右移然后&1的操作,因为如果n是负数的话,右移最高位会补1
法1:引入flag=1,使其不断左移
有个小细节需要注意就是如果直接if(n&flag!= 0)是会报错的
法2:n-1 可以把n的最右边的1变成0,将1右边的0全部变为1,1左边的位全都保持不变,(n-1)&n的结果只会将最右边的1变为0,其余位全都保持不变,在不断将最右边的1变成0的过程就会使得最后n变成0
Leetcode 201. Bitwise AND of Numbers Range(某范围内数据的“与“位运算)
Given a range [m, n] where 0 <= m <=n <= 2147483647, return the bitwise AND of all numbers in this range,inclusive.
For example, given the range [5, 7], youshould return 4.
观察下面的规律
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
可以看到,第一位的变化是0101010的变化,第二位是00110011的变化,第三位是0000111100001111的变化,以此类推第d位就是pow(2,d-1)个0 pow(2,d-1)个1的变化,因此,从m~n的范围中,pow(2,d-1)< n-m的位d与出来的结果都是0,其余的位置就要取决于m和n本身的大小了
Leetcode 476. Number Complement
Given a positive integer, output itscomplement number. The complement strategy is to flip the bits of its binaryrepresentation.
Note:
- The given integer is guaranteed to fit within the range of a 32-bit signed integer.
- You could assume no leading zero bit in the integer’s binary representation.
Example 1:
Input: 5
Output: 2
Explanation: The binaryrepresentation of 5 is 101 (no leading zero bits), and its complement is 010.So you need to output 2.
Example 2:
Input: 1
Output: 0
Explanation: The binaryrepresentation of 1 is 1 (no leading zero bits), and its complement is 0. Soyou need to output 0.
选择先对num进行非操作再进行与操作会比直接进行异或操作要快。
其中Integer.highestOneBit(n)的功能是,取数字n的二进制表示最高的一位,并将后位全部补0
2. 数学计算
Leetcode 168. Excel Sheet Column Title excel的列
Given a positive integer,return its corresponding column title as appear in an Excel sheet.
For example:
1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB
十进制变成26进制
Leetcode 171. Excel Sheet Column Number
Related to question ExcelSheet Column Title
Given a column title asappear in an Excel sheet, return its corresponding column number.
For example:
A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28
26进制变成10进制
Leetcode 172. Factorial Trailing Zeroes
Given an integer n, return the number oftrailing zeroes in n!.
Note: Yoursolution should be in logarithmic time complexity.
看结果的末尾一共有多少个0,其实就是看这个数的阶乘能分出多少个5, 1~n中有n/5个5的倍数,至少有n/5个5,但是考虑到还会有25(5*5,是5的倍数但是包含两个5),125(包含3个5)的情况出现,所以要写循环。
Leetcode 264. Ugly Number II 求第n个丑数(剑指offer34)
Write a program to find the n
-thugly number.
Ugly numbers are positive numbers whose prime factors onlyinclude 2,3, 5
. For example, 1,2, 3, 4, 5, 6, 8, 9, 10, 12
is the sequence of the first 10
ugly numbers.
Note that 1
is typically treated as an ugly number, and n doesnot exceed 1690.
丑数就是因子只有2,3,5 的数字,那只要用我前面得到的丑数依次去乘2,3,5就可以得到新的丑数,但是要注意乘出来之后数的大小
Leetcode 233. Number of Digit One 从1~n中所有数字中出现1的次数和(剑指offer 32)
Given an integer n, count thetotal number of digit 1 appearing in all non-negative integers less than orequal to n.
For example:
Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
11算出现两次,举个栗子对于一个很大的数234567,先看从34568~234567(工200000个数)中出现的1的个数,先看1开头的(只算上首位为1的数量),那对于上述范围,1开头的数字一共有100000个,注意这边因为234567是包含1000000~200000的,如果变成34568~134567的话实际上1开头的数字就只有34567个了,然后再考虑除首位以外的位置出现1的可能性,由于34568~234567这200000个数字出去首位一共是5位,那个其中一位出现1 的次数是10^4(其余的数字都是0~9),对于5位则有1出现的次数是5 * 10^4,到现在为止34568~234567这个范围内1出现的次数就计算出来了,接下来只需要用同样的方法计算4568~34567中1出现的次数,然后递归即可。
扩展:如果Leetcode 233题目改成只要出现1就算一次的话,那么1~n中一共有几次
还是用上述的方法,只不过这次不是计算1的次数,是计算所有位置都不出现1的数字的数量,然后用总数相减即可(代码就略啦啦啦啦~~)
3. 完成某种数学符号的功能
Leetcode 166. Fraction to Recurring Decimal
Given two integersrepresenting the numerator and denominator of a fraction, return the fractionin string format.
If the fractional part is repeating,enclose the repeating part in parentheses.
For example,
- Given numerator = 1, denominator = 2, return "0.5".
- Given numerator = 2, denominator = 1, return "2".
- Given numerator = 2, denominator = 3, return "0.(6)".
就是按照除法的步骤进行循环,需要考虑的情况较多,其中关于两个数的正负问题,如果相除的结果绝对值不大于1,是不会带着正负号的,所以要预先判断一下结果的正负。考虑到越界问题,可以用一个很无赖的方法,就是将int转成long来解决,然后可以在数据结构的使用上注意可以稍微的提快速度,比如说可以用StringBuffer代替String,利用位运算符等,上代码:
注:.是个特殊符号不能用split分开
附:String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” +“ simple” + “ test”;
StringBuffer Sb = newStringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你会很惊讶的发现,生成 StringS1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “This is only a” +“ simple” + “test”; 其实就是:
String S1 = “This is only asimple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做
在大部分情况下 StringBuffer >String
StringBuffer
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
在大部分情况下 StringBuilder >StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。