202. 快乐数
该题的难点主要在:如何检测出会发生循环。
如果检测出会发生循环,那么永远不可能变为1,则返回 false。
方法一:利用「哈希表可以快速判断元素是否在集合中」的特点。
把出现过的值加入到集合中,如果当前值存在集合中,那么就意味着会发生循环,返回 false。
方法二:判断链表是否有环的问题,弗洛伊德循环查找算法
方法三:数学法
所有的非快乐数只存在一个循环,也就是:4 ->16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4
不存在其他循环,只要出现这几个数中的其中一个,就可以判定一定会发生循环,返回 false。
206. 反转链表
反转的步骤:
- 记录要反转的节点为 curr,记录 curr 的前一个节点为 prev,记录 curr 的后一个节点为 next
- 改变 curr 的指向,即 curr.next = prev
- prev 前进一个节点,即 prev = curr
- curr 前进一个节点,即 curr = next
- next 前进一个节点,即 next = curr.next(即上面的记录 curr 的后一个节点为 next,循环的起始)
循环往复,直到 curr 为 null,prev 即为反转链表的头节点
class Solution {public ListNode reverseList(ListNode head) {// curr 的前一个节点ListNode prev = null;ListNode curr = head;// curr 的后一个节点ListNode next = null;while (curr != null) {// next 前进next = curr.next;// 反转curr.next = prev;// prev 前进prev = curr;// curr 前进curr = next;}return prev;}}
class Solution {public ListNode reverseList(ListNode head) {ListNode node = recursion(null, head);return node;}private ListNode recursion(ListNode prev, ListNode curr) {if (curr == null) {return prev;}ListNode node = recursion(curr, curr.next);curr.next = prev;return node;}}
class Solution {public ListNode reverseList(ListNode head) {ListNode node = recursion(head);return node;}private ListNode recursion(ListNode node) {if ( node == null || node.next == null) {return node;}ListNode node1 = recursion(node.next);node.next.next = node;node.next = null;return node1;}}
209. 长度最小的子数组
class Solution {public int minSubArrayLen(int target, int[] nums) {{/*时间复杂度:O(n)*/}// l、r 是窗口的左右边界int l = 0;int r = 0;// sum 是窗口内 nums 的总和int sum = 0;int result = Integer.MAX_VALUE;while (r < nums.length) {sum += nums[r];while (sum >= target && l <= r) {result = Math.min(result, r - l + 1);sum -= nums[l];l++;}r++;}if (result == Integer.MAX_VALUE) {return 0;} else {return result;}}}
216. 组合总和 III
class Solution {List<List<Integer>> results = new ArrayList<>();List<Integer> result = new ArrayList<>();int k;int n;public List<List<Integer>> combinationSum3(int k, int n) {this.k = k;this.n = n;backtracking(1, 0);return results;}// s 代表集合的起始元素 [s...9]public void backtracking(int s, int sum) {if (result.size() == k) {if (sum == n) {results.add(new ArrayList<>(result));}return;}for (int i = s; i <= 9; i++) {result.add(i);backtracking(i + 1, sum + i);result.remove(result.size() - 1);}}}
class Solution {List<List<Integer>> results = new ArrayList<>();List<Integer> result = new ArrayList<>();int k;int n;public List<List<Integer>> combinationSum3(int k, int n) {this.k = k;this.n = n;backtracking(1, 0);return results;}// s 代表集合的起始元素 [s...9]public void backtracking(int s, int sum) {if (result.size() == k) {if (sum == n) {results.add(new ArrayList<>(result));}return;}// 剪枝:数量不足的情况 和 相加之和必定不能满足条件的情况(和太大、和太小)for (int i = s; i <= 9 && (result.size() + 10 - i) >= k && (sum + (k - result.size()) * i) <= n && (sum + (k - result.size()) * 9) >= n; i++) {result.add(i);backtracking(i + 1, sum + i);result.remove(result.size() - 1);}}}
有效的字母异位词
有思路,不写了
方法一:先对字符排序,再逐个比较
方法二:哈希表
