目录
- 70. 爬楼梯(简单)
- 509. 斐波那契数(简单)
- 1. 两数之和(简单)
- 88. 合并两个有序数组(简单)
- 283. 移动零(简单)
- 448. 找到所有数组中消失的数字(简单)
- 21. 合并两个有序链表(简单)
- 83. 删除排序链表中的重复元素(简单)
- 141. 环形链表(简单)
- 142. 环形链表 II(中等)
- 160. 相交链表(简单)
70. 爬楼梯(简单)
递归(自顶向下)
时空复杂度:n2,1
class Solution {
public int climbStairs(int n) {
if (n == 1) return 1;
if (n == 2) return 2;
return climbStairs(n - 1) + climbStairs(n - 2);
}
}
递归+哈希表
时空复杂度:n,n
class Solution {
private HashMap<Integer, Integer> hashMap = new HashMap<>();
public int climbStairs(int n) {
if (n == 1) return 1;
if (n == 2) return 2;
int pre = 0, prePre = 0;
if (hashMap.get(n) != null) {
return hashMap.get(n);
} else {
int res = climbStairs(n - 1) + climbStairs(n - 2);
hashMap.put(n, res);
return res;
}
}
}
循环解法(自底向上)
时空复杂度:n,1
class Solution {
public int climbStairs(int n) {
if (n == 1) return 1;
if (n == 2) return 2;
int pre = 2, prePre = 1;
int res = 0;
for (int i = 3; i <= n; i++) {
res = pre + prePre;
prePre = pre;
pre = res;
}
return res;
}
}
509. 斐波那契数(简单)
递归(自顶向下)
时空复杂度:n2, 1
class Solution {
public int fib(int n) {
if(n==0) return 0;
if(n==1) return 1;
return fib(n-1)+fib(n-2);
}
}
递归+哈希表
时空复杂度:n,n
class Solution {
private HashMap<Integer, Integer> hashMap = new HashMap<>();
public int fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
if (hashMap.get(n) != null) {
return hashMap.get(n);
} else {
int res = fib(n - 1) + fib(n - 2);
hashMap.put(n, res);
return res;
}
}
}
循环解法(自底向上)
时空复杂度:n,1
class Solution {
public int fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
int res = 0, pre = 1, prePre = 0;
for (int i = 2; i <= n; i++) {
res = pre + prePre;
prePre = pre;
pre = res;
}
return res;
}
}
1. 两数之和(简单)
暴力
时空复杂度:n2, 1
class Solution {
public int[] twoSum(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};
}
}
return null;
}
}
哈希表
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> hashMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (hashMap.get(target - nums[i]) != null) {
return new int[]{hashMap.get(target - nums[i]), i};
} else {
hashMap.put(nums[i], i);
}
}
return null;
}
}
88. 合并两个有序数组(简单)
暴力
时空复杂度:nlogn(快排),1
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
for (int i = 0; i < n; i++) {
nums1[m + i] = nums2[i];
}
Arrays.sort(nums1);
}
}
空间换时间
时空复杂度:n,n
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
ArrayList<Integer> list = new ArrayList<>();
int i = 0, j = 0;
for (; i < m && j < n; ) {//比较大小,除非某一方到头了
if (nums1[i] < nums2[j]) {
list.add(nums1[i++]);
} else {
list.add(nums2[j++]);
}
}
if (i != m) {//nums1到头了,把nums2直接接过来就行了,无需比较
for (int k = i; k < m; k++) {
list.add(nums1[k]);
}
}
if (j != n) {//nums2同理
for (int k = j; k < n; k++) {
list.add(nums2[k]);
}
}
for (int k = 0; k < nums1.length; k++) {//转移到nums1中
nums1[k] = list.get(k);
}
}
}
逆序遍历
时空复杂度:n,1
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1, j = n - 1, index = nums1.length - 1;
while (i >= 0 && j >= 0) {
if (nums1[i] < nums2[j]) {
nums1[index--] = nums2[j--];
} else {
nums1[index--] = nums1[i--];
}
}
if (i >= 0) {
while (index >= 0) {
nums1[index--] = nums1[i--];
}
}
if (j >= 0) {
while (index >= 0) {
nums1[index--] = nums2[j--];
}
}
}
}
283. 移动零(简单)
双指针
时空复杂度:n,1
class Solution {
public void moveZeroes(int[] nums) {
int j = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
swap(nums, i, j);
j++;
}
}
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
448. 找到所有数组中消失的数字(简单)
时空复杂度:n,1
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
ArrayList<Integer> list = new ArrayList<>();
int n = nums.length;
for (int i = 0; i < n; i++) {//第一次便利,标记出现过的数字
int x = (nums[i]-1) % n;
nums[x] += n;
}
for (int i = 0; i < n; i++) {//第二次便利,没有标记的下表就是结果
if (nums[i] <= n) list.add(i+1);
}
return list;
}
}
21. 合并两个有序链表(简单)
时空复杂度:n,1
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null) return list2;
if (list2 == null) return list1;
ListNode dummy = new ListNode(-1), p = dummy, p1 = list1, p2 = list2;
while (null != p1 && null != p2) {
if (p1.val < p2.val) {
p.next = p1;
p = p.next;
p1 = p1.next;
} else {
p.next = p2;
p = p.next;
p2 = p2.next;
}
}
if (null != p1) {
p.next = p1;
}
if (null != p2) {
p.next = p2;
}
return dummy.next;
}
}
83. 删除排序链表中的重复元素(简单)
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null) return head;
ListNode p = head;
while (p.next != null) {
if (p.val == p.next.val) {
p.next = p.next.next;
} else {
p = p.next;
}
}
return head;
}
}
141. 环形链表(简单)
时空复杂度:n,1
public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null) return false;
ListNode slow = head, fast = head;
while (fast!=null&&fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}
}
142. 环形链表 II(中等)
时空复杂度:n,1
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null) return head;
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) break;
}
if (fast == null || fast.next == null) return null;
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
160. 相交链表(简单)
时空复杂度:n,1
方法一:暴力
方法二:哈希表
方法三:双指针
方法四:长度统一
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p1 = headA, p2 = headB;
while (p1 != p2) {
p1 = p1 == null ? headB : p1.next;
p2 = p2 == null ? headA : p2.next;
}
return p1;
}
}