首先额外增加一题[因为做到了]:有n个台阶 一次只能有1步或者2步,有多少种走法?
题目分析:
找通项
当 n=1 的时候,走法有1个 => [1步]
当 n=2 的时候,走法有2个 => [1步 走2次] [2步 走1次]
当 n=3 的时候,走法有3个 => [1步 走3次] [2步1次 1步1次] [1步1次 2步1次]
当 n=4 的时候,走法有5个 => [1步 走4次] [1步 走2次 2步1次] [2步 走2次] [2步 走1次 1步 走2次] [1步 走1次 2步 走1次 1步 走1次]
此时就有了一般的规律,斐波那契数列 => f(n) = f(n-1) + f(n-2)实际上再仔细看题目,其实就是当n=4的时候,分为3台阶和1台阶 那么此时就是n=3 的次数 同时,再分为2台阶和2台阶 那么就是n=2 的次数 那么n=4的时候,就是 n=3 + n=2 的次数
那么实现可以使用递归实现,也可以使用迭代实现 这里递归是最消耗时间的 此时迭代速度巨快 下面测试一下 n=50时 的各自消耗的时间[数字大小超过 int 的范围暂且不计]
代码实现
public class Solution {
public static void main(String[] args) {
long start = System.currentTimeMillis();
System.out.println(getWays(50));
System.out.println("递归:" + (System.currentTimeMillis() - start) + ":ms");
start = System.currentTimeMillis();
System.out.println(getWays01(50));
System.out.println("迭代:" + (System.currentTimeMillis() - start) + ":ms");
}
public static int getWays01(int n) {
if (n == 1 || n == 2) {
return n;
}
int one = 1;
int two = 2;
int sum = 0;
for (int i = 3; i <= n; i++) {
sum = one + two;
one = two;
two = sum;
}
return sum;
}
public static int getWays(int n) {
if (n == 1 || n == 2) {
return n;
} else {
return getWays(n - 1) + getWays(n - 2);
}
}
}
测试结果
-1109825406
递归:44733:ms
-1109825406
迭代:0:ms
LeetCode 两数之和 [简单]
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
题目分析:
方法1:这样的题目很容易想到的就是暴力法
双重循环解决,时间复杂度 O(n^2),空间复杂度O(1)方法2:把数据的下标和值存储到Map中,然后取出一一对比
为了对运行时间复杂度进行优化,我们需要一种更有效的方法来检查数组中是否存在目标元素。如果存在,我们需要找出它的索引。保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。通过以空间换取速度的方式,我们可以将查找时间从 O(n)O(n) 降低到 O(1)O(1)。哈希表正是为此目的而构建的,它支持以 近似 恒定的时间进行快速查找。我用“近似”来描述,是因为一旦出现冲突,查找用时可能会退化到 O(n)O(n)。但只要你仔细地挑选哈希函数,在哈希表中进行查找的用时应当被摊销为 O(1)O(1)
一个简单的实现使用了两次迭代。在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target−nums[i])是否存在于表中。注意,该目标元素不能是nums[i] 本身!
时间复杂度 O(n) 额外的Map开销,空间复杂度O(n)
方法3:一遍哈希表
在进行迭代并将元素插入到表中的同时,我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到了对应解,并立即将其返回。时间复杂度O(n),空间复杂度O(n)
代码实现
public class Solution {
public static void main(String[] args) {
int[] nums = {2, 7, 7, 11, 15};
int target = 17;
int[] result = new LeetCode_01_TwoNumbersSum().twoSum_03(nums, target);
for (int i = 0; i < result.length; i++) {
System.out.print(result[i] + " ");
}
}
public int[] twoSum_03(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int otherNum = target - nums[i];
if (map.containsKey(otherNum)) {
return new int[]{map.get(otherNum), i};
}
map.put(nums[i], i);
}
throw new NoSuchElementException();
}
public int[] twoSum_02(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int otherNum = target - nums[i];
if (map.containsKey(otherNum) && map.get(otherNum) != i) {
return new int[]{i, map.get(otherNum)};
}
}
throw new NoSuchElementException();
}
public int[] twoSum_01(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return new int[]{i, j};
}
}
}
throw new NoSuchElementException();
}
}
测试
0 4