爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
动态规划
爬上第n 层楼梯,是一般有两种方法,第n-1 层爬一层到达,或者是第n-2 层爬两层到达,以此类推,再算出第n-1 层与第n-2 的层,所以可以用递归,但是反过来的递推效率更高,即前面可知第n 层可以由第n-2 层与第n-1 层,然后不断算到第n 层。
public int climbStairs(int n) {
if (n < 1) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
int count = 3;
int a=1;
int b=2;
int sum = 0;
while (count <= n){
sum = a+b;
a = b;
b = sum;
count++;
}
return sum;
}
法二
递归超时,所以加入map ,把算过的存一下,如果再用到就不算了,节省性能开销,提高效率。
Map<Integer,Integer> map = new HashMap<>();
public int climbStairs(int n) {
if (n < 1) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
if (map.containsKey(n)){
return map.get(n);
}else {
int v = climbStairs(n-1)+climbStairs(n-2);
map.put(n,v);
return v;
}
}
二进制求和
给定两个二进制字符串,返回他们的和(用二进制表示)。
输入为非空字符串且只包含数字 1
和 0
。
示例 1:
输入: a = "11", b = "1"
输出: "100"
示例 2:
输入: a = "1010", b = "1011"
输出: "10101"
public String addBinary(String a, String b) {
int len_a = a.length();
int len_b = b.length();
int len = (len_a > len_b ? len_a : len_b) + 1; // 这个+1 是为进位准备的
int[] t_a = new int[len];
int i = 0;
for (i = 0; i < len_a; i++){
// len - len_a 找到应该填充的起始位置,然后 + i 是从0 开始,逐个往后将值赋上
t_a[i + len - len_a] = Integer.parseInt(a.charAt(i) + "");
}
int[] t_b = new int[len];
for (i = 0; i < len_b; i++){
t_b[i + len - len_b] = Integer.parseInt(b.charAt(i) + "");
}
int temp = 0; // 进位值,进位的话该值为1
int[] res = new int[len];
for (i = len-1;i >= 0;i--){
res[i] = getResult(t_a[i],t_b[i],temp);
temp = getTemp(t_a[i],t_b[i],temp);
}
StringBuilder sb = new StringBuilder();
for (i = 0; i < len; i++){
// 找到开始位为1 的
if (res[i] == 1){
for (int j = i; j< len ;j++){
sb.append(res[j]);
}
break;
}
}
if (i == len)
return "0";
return sb.toString();
}
/**
* 由二进制相加的特点
*/
public int getResult(int i, int j, int temp) {
return i ^ j ^ temp;
}
/**
* 获取进位值0,1 都不进位,所以返回0
* > 1 才进位
*/
public int getTemp(int i, int j, int temp) {
if (i + j + temp > 1)
return 1;
return 0;
}
旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入:[1,2,3,4,5,6,7] 和 k = 3
输出:[5,6,7,1,2,3,4]
解释: 向右旋转 1 步: [7,1,2,3,4,5,6] 向右旋转 2 步: [6,7,1,2,3,4,5] 向右旋转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入: [-1,-100,3,99] 和 k = 2 输出: [3,99,-1,-100] 解释: 向右旋转 1 步: [99,-1,-100,3] 向右旋转 2 步: [3,99,-1,-100]
取模运算
public void rotate(int[] nums, int k) {
int[] temp = new int[nums.length];
for (int i=0;i<nums.length;i++){
int index = (i+k)%nums.length;
temp[index] = nums[i];
}
System.arraycopy(temp, 0, nums, 0, nums.length);
}