刷题笔记,记录难点重点

本文从 Leetcode 中精选大概 200 左右的题目,去除了某些繁杂但是没有多少算法思想的题目,同时保留了面试中经常被问到的经典题目。

数据结构相关

链表

总结:用head遍历还是用cur遍历看是否只遍历一遍

1. 找出两个链表的交点 [Done]

160. Intersection of Two Linked Lists (Easy)

2. 链表反转 [Done]

206. Reverse Linked List (Easy)

3. 归并两个有序的链表 [Done]

21. Merge Two Sorted Lists (Easy)

4. 从有序链表中删除重复节点 [Done]

83. Remove Duplicates from Sorted List (Easy)

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode cur = head;
        while(cur.next != null) {//因为有cur.next.val所以要判断cur.next是否为空
            if (cur.next.val == cur.val){
                cur.next = cur.next.next;
            }else{//注意,如果找到重复,则cur保持不动再判断一轮
                cur=cur.next;
            }
        }
        return head;

    }
}
5. 删除链表的倒数第 n 个节点 [Done]

19. Remove Nth Node From End of List (Medium)

6. 交换链表中的相邻结点 [Done]

24. Swap Nodes in Pairs (Medium)
在这里插入图片描述

方法一:迭代
class Solution {
	public ListNode swapPairs(ListNode head) {
		//增加一个特殊节点方便处理
		ListNode p = new ListNode(-1);
		p.next = head;
		//创建a,b两个指针,这里还需要一个tmp指针
		ListNode a = p;
		ListNode b = p;
		ListNode tmp = p;
		while(b!=null && b.next!=null && b.next.next!=null) {
			//a前进一位,b前进两位
			a = a.next;
			b = b.next.next;
			//这步很关键,tmp指针用来处理边界条件的
			//假设链表是1->2->3->4,a指向1,b指向2
			//改变a和b的指向,于是就变成2->1,但是1指向谁呢?
			//1是不能指向2的next,1应该指向4,而循环迭代的时候一次处理2个节点
			//1和2的关系弄清楚了,3和4的关系也能弄清楚,但需要一个指针来处理
			//2->1,4->3的关系,tmp指针就是干这个用的
			tmp.next = b;
			a.next = b.next;
			b.next = a;
			//现在链表就变成2->1->3->4
			//tmp和b都指向1节点,等下次迭代的时候
			//a就变成3,b就变成4,然后tmp就指向b,也就是1指向4
			tmp = a;
			b = a;
		}
		return p.next;
	}
}

在这里插入图片描述

class Solution {
	public ListNode swapPairs(ListNode head) {
		//递归的终止条件
		if(head==null || head.next==null) {
			return head;
		}
		//假设链表是 1->2->3->4
		//这句就先保存节点2
		ListNode tmp = head.next;
		//继续递归,处理节点3->4
		//当递归结束返回后,就变成了4->3
		//于是head节点就指向了4,变成1->4->3
		head.next = swapPairs(tmp.next);
		//将2节点指向1
		tmp.next = head;
		return tmp;
	}
}

作者:wang_ni_ma
链接:https://leetcode.cn/problems/swap-nodes-in-pairs/solution/dong-hua-yan-shi-24-liang-liang-jiao-huan-lian-bia/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
7. 链表求和 [Done]

445. Add Two Numbers II (Medium)
注意:
(1)栈的定义:Deque stack = new ArrayDeque();
(2)栈的相关操作:stack.push();stack.pop();stack,isEmpyty();
(3)int a = stack1.isEmpty() ? 0 : stack1.pop();用这个避免有一个栈为空
(4)注意加法的操作步骤

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Deque<Integer> stack1 = new ArrayDeque<Integer>();
        Deque<Integer> stack2 = new ArrayDeque<Integer>();
        while (l1 != null) {
            stack1.push(l1.val);
            l1 = l1.next;
        }
        while (l2 != null) {
            stack2.push(l2.val);
            l2 = l2.next;
        }
        int carry = 0;//保证carry是全局变量
        ListNode ans = null;
        while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
            int a = stack1.isEmpty() ? 0 : stack1.pop();
            int b = stack2.isEmpty() ? 0 : stack2.pop();
            int cur = a + b + carry;//先相加再将carry除10可以保证carry是上一位的
            carry = cur / 10;//每轮carrrys是会更新的
            cur %= 10; //cur为除10取余
            ListNode curnode = new ListNode(cur);
            curnode.next = ans;
            ans = curnode;
        }
        return ans;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/add-two-numbers-ii/solution/liang-shu-xiang-jia-ii-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
8. 回文链表 [Done]

234. Palindrome Linked List (Easy)

9. 分隔链表 [Done]

725. Split Linked List in Parts(Medium)
注意:
(1)这道题考察的重点是将链表建立成数组,每个位置保存的是链表的头节点
(2)因为要返回下一段的前一个节点,所以少循环一次
(3)删除或断开时注意用临时节点保存后面的地址再进行删除或断开的操作

class Solution {
    public ListNode[] splitListToParts(ListNode head, int k) {
        int length = 0;
        ListNode cur=head;
        while(cur!= null){
            length++;
            cur = cur.next;
        }
        cur = head;
        ListNode tmp ;
        ListNode[] parts = new ListNode[k];
        for (int i = 0;i<k&&cur!=null ;i++){
            parts[i] = cur;
            int num = length/k + (i< length%k?1:0);
            for (int j = 0;j<num-1;j++){因为要返回下一段的前一个节点,所以少循环一次
                cur = cur.next;
            }
            tmp =cur.next;
            cur.next = null;
            cur = tmp;

        }
        return parts;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/split-linked-list-in-parts/solution/fen-ge-lian-biao-by-leetcode-solution-wevt/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
10. 链表元素按奇偶聚集 [Done]

328. Odd Even Linked List (Medium)
注意:
(1)不用的元素释放为空
(2)每次跳两格的题如双指针,都要注意循环结束条件和循环结束后cur的位置,奇数偶数cur结束循环的位置不同

class Solution {
    public ListNode oddEvenList(ListNode head) {
        if(head ==  null ||head.next == null ||head.next.next == null){
            return head;
        }
        ListNode nexthead = new ListNode(-1);
        ListNode cur=head;
        ListNode tmp = nexthead;
        while(cur != null && cur.next!=null){
            tmp.next = cur.next;
            cur.next = cur.next.next;
            tmp.next.next = null
            tmp = tmp.next;
            cur = cur.next;
        }
        cur = head;
        while(cur.next!= null ){
            cur = cur.next;
        }
        cur.next = nexthead.next;

        return head;

    }
}

递归
1. 树的高度 [Done]

104. Maximum Depth of Binary Tree (Easy)
广度优先遍历
在这里插入代码片在这里插入图片描述

class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        int ans = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size > 0) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
                size--;
            }
            ans++;
        }
        return ans;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/maximum-depth-of-binary-tree/solution/er-cha-shu-de-zui-da-shen-du-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

深度优先遍历
在这里插入图片描述

class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null){
            return 0;
        }
        int rightHeight = maxDepth(root.right);
        int leftHeight = maxDepth(root.left);
        return Math.max(rightHeight,leftHeight)+1;

    }
}
2. 平衡树 [Done]

110. Balanced Binary Tree (Easy)

3. 两节点的最长路径 [Done]

543. Diameter of Binary Tree (Easy)

4. 翻转树 [Done]

226. Invert Binary Tree (Easy)
成功写出来了敲击开心
`

 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null){
            return null;
        }
        invertTree(root.left);
        invertTree(root.right);
        TreeNode node = root.right;
        root.right = root.left;
        root.left = node;
        return root;
    }
}
5. 归并两棵树 [Done]

617. Merge Two Binary Trees (Easy)
注意对空节点的处理方法:
if(root1 == null){
return root2;
}
if(root2 == null){
return root1;
}

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null){
            return root2;
        }
        if(root2 == null){
            return root1;
        }
        TreeNode root = new TreeNode(root1.val+root2.val);
        root.left = mergeTrees(root1.left,root2.left);//error:TreeeNode root.left = mergeTree....
        root.right  = mergeTrees(root1.right,root2.right);
        return root;
    }
}
6. 判断路径和是否等于一个数 [Done]

112. Path Sum (Easy)

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null){
            return false;
        }
        targetSum-=root.val; 
        if((root.left==null&&root.right == null)&&targetSum == 0){
            return true;
            }
        boolean leftBool = hasPathSum(root.left,targetSum);
        boolean rightBool = hasPathSum(root.right,targetSum);
        return (leftBool||rightBool);

    }
}
7. 统计路径和等于一个数的路径数量

437. Path Sum III (Easy)

8. 子树

572. Subtree of Another Tree (Easy)

9. 树的对称

101. Symmetric Tree (Easy)

10. 最小路径

111. Minimum Depth of Binary Tree (Easy)

11. 统计左叶子节点的和

404. Sum of Left Leaves (Easy)

12. 相同节点值的最大路径长度

687. Longest Univalue Path (Easy)

13. 间隔遍历
[337. House Robber III (Medium)](https://leetcode-cn.com/problems/house-robber-iii/description/)
14. 找出二叉树中第二小的节点
[671. Second Minimum Node In a Binary Tree (Easy)](https://leetcode-cn.com/problems/second-minimum-node-in-a-binary-tree/description/)
层次遍历
1. 一棵树每层节点的平均数

637. Average of Levels in Binary Tree (Easy)

2. 得到左下角的节点

513. Find Bottom Left Tree Value (Easy)

前中后序遍历
1. 非递归实现二叉树的前序遍历 [Done]

144. Binary Tree Preorder Traversal (Medium)

2. 非递归实现二叉树的后序遍历 [Done]

145. Binary Tree Postorder Traversal (Medium)

3. 非递归实现二叉树的中序遍历 [Done]

94. Binary Tree Inorder Traversal (Medium)

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> arr =  new ArrayList<Integer>();
        if (root == null){
            return arr;
        }
        Stack<TreeNode> s = new Stack<TreeNode>();
        while(!s.isEmpty() || root != null){//注意是或而非且
            if (root != null){
                s.push(root);
                root = root.left;
            }
            else {
                root = s.pop();//注意把s.pop赋给root
                arr.add(root.val);
                root = root.right;
            }
        }
        return arr;

    }
BST
  1. 修剪二叉查找树
    669. Trim a Binary Search Tree (Easy)

  2. 寻找二叉查找树的第 k 个元素
    230. Kth Smallest Element in a BST (Medium)

  3. 把二叉查找树每个节点的值都加上比它大的节点的值
    538. Convert BST to Greater Tree (Easy)

  4. 二叉查找树的最近公共祖先
    235. Lowest Common Ancestor of a Binary Search Tree (Easy)

  5. 二叉树的最近公共祖先
    236. Lowest Common Ancestor of a Binary Tree (Medium)

  6. 从有序数组中构造二叉查找树
    108. Convert Sorted Array to Binary Search Tree (Easy)

  7. 根据有序链表构造平衡的二叉查找树
    109. Convert Sorted List to Binary Search Tree (Medium)

  8. 在二叉查找树中寻找两个节点,使它们的和为一个给定值
    653. Two Sum IV - Input is a BST (Easy)

  9. 在二叉查找树中查找两个节点之差的最小绝对值
    530. Minimum Absolute Difference in BST (Easy)

  10. 寻找二叉查找树中出现次数最多的值
    501. Find Mode in Binary Search Tree (Easy)

Trie
  1. 实现一个 Trie
    208. Implement Trie (Prefix Tree) (Medium)

  2. 实现一个 Trie,用来求前缀和
    677. Map Sum Pairs (Medium)

栈和队列

  1. 用栈实现队列
    232. Implement Queue using Stacks (Easy)

  2. 用队列实现栈
    225. Implement Stack using Queues (Easy)

  3. 最小值
    155. Min Stack (Easy)

  4. 用栈实现括号匹配
    20. Valid Parentheses (Easy)

  5. 数组中元素与下一个比它大的元素之间的距离
    739. Daily Temperatures (Medium)

  6. 循环数组中比当前元素大的下一个元素
    503. Next Greater Element II (Medium)

哈希表

遍历哈希表
 Set<Character> keys = map.keySet();
        for(Character key:keys){可以用下面代码得到哈希表中存放字母的重复个数
Map<Character, Integer> table = new HashMap<Character, Integer>();
for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            table.put(ch, table.getOrDefault(ch, 0) + 1);
        }
getOrDefault方法
hashmap.getOrDefault(Object key, V defaultValue)
返回 key 相映射的的 value,如果给定的 key 在映射关系中找不到,则返回指定的默认值。
value记录出现次数
table.put(ch, table.getOrDefault(ch, 0) + 1)
  1. 数组中两个数的和为给定值
    1. Two Sum (Easy)

  2. 判断数组是否含有重复元素
    217. Contains Duplicate (Easy)

  3. 最长和谐序列
    594. Longest Harmonious Subsequence (Easy)

  4. 最长连续序列
    128. Longest Consecutive Sequence (Hard)

字符串

  1. 字符串循环移位包含

    给定两个字符串 s1 和 s2,要求判定 s2 是否能够被 s1 做循环移位得到的字符串包含。

    s1 进行循环移位的结果是 s1s1 的子字符串,因此只要判断 s2 是否是 s1s1 的子字符串即可。

  2. 字符串循环移位

    将字符串向右循环移动 k 位。

    将 abcd123 中的 abcd 和 123 单独翻转,得到 dcba321,然后对整个字符串进行翻转,得到 123abcd。

  3. 字符串中单词的翻转

    将每个单词翻转,然后将整个字符串翻转。

  4. 两个字符串包含的字符是否完全相同 [Done]
    242. Valid Anagram (Easy)
    **方法一:排序法,**注意字符串转数组,数组的排序,数组的比较语法

class Solution {
    public boolean isAnagram(String s, String t) {
        if(s.length() != t.length()){
            return false;
        }
        char[] arr1 = s.toCharArray();
        char[] arr2 = t.toCharArray();
        Arrays.sort(arr2); // arr1.sort();
        Arrays.sort(arr1); // Array.sort()
        return Arrays.equals(arr1, arr2);
    }
}

方法二:利用哈希表

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        Map<Character, Integer> table = new HashMap<Character, Integer>();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            table.put(ch, table.getOrDefault(ch, 0) + 1);
        }
        for (int i = 0; i < t.length(); i++) {
            char ch = t.charAt(i);
            table.put(ch, table.getOrDefault(ch, 0) - 1);
            if (table.get(ch) < 0) {
                return false;
            }
        }
        return true;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/valid-anagram/solution/you-xiao-de-zi-mu-yi-wei-ci-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  1. 计算一组字符集合可以组成的回文字符串的最大长度 [Done]
    409. Longest Palindrome (Easy)

  2. 字符串同构 [Done]
    205. Isomorphic Strings (Easy)

  3. 回文子字符串个数 [Done]
    647. Palindromic Substrings (Medium)
    中心扩展法:中心点有count*2-1个,左节点:center/2,右节点:left+center%2

比如对一个字符串 ababa,选择最中间的 a 作为中心点,往两边扩散,第一次扩散发现 left 指向的是 b,right 指向的也是 b,所以是回文串,继续扩散,同理 ababa 也是回文串。
这个是确定了一个中心点后的寻找的路径,然后我们只要寻找到所有的中心点,问题就解决了。
中心点一共有多少个呢?看起来像是和字符串长度相等,但你会发现,如果是这样,上面的例子永远也搜不到 abab,想象一下单个字符的哪个中心点扩展可以得到这个子串?似乎不可能。所以中心点不能只有单个字符构成,还要包括两个字符,比如上面这个子串 abab,就可以有中心点 ba 扩展一次得到,所以最终的中心点由 2 * len - 1 个,分别是 len 个单字符和 len - 1 个双字符。
如果上面看不太懂的话,还可以看看下面几个问题:
为什么有 2 * len - 1 个中心点?
aba 有5个中心点,分别是 a、b、c、ab、ba
abba 有7个中心点,分别是 a、b、b、a、ab、bb、ba
什么是中心点?
中心点即 left 指针和 right 指针初始化指向的地方,可能是一个也可能是两个
为什么不可能是三个或者更多?
因为 3 个可以由 1 个扩展一次得到,4 个可以由两个扩展一次得到

class Solution6472 {
    public int countSubstrings(String s) {
        // 中心扩展法
        int ans = 0;
        for (int center = 0; center < 2 * s.length() - 1; center++) {
            // left和right指针和中心点的关系是?
            // 首先是left,有一个很明显的2倍关系的存在,其次是right,可能和left指向同一个(偶数时),也可能往后移动一个(奇数)
            // 大致的关系出来了,可以选择带两个特殊例子进去看看是否满足。
            int left = center / 2;
            int right = left + center % 2;
            while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
                ans++;
                left--;
                right++;
            }
        }
        return ans;
    }
}

作者:jawhiow
链接:https://leetcode.cn/problems/palindromic-substrings/solution/liang-dao-hui-wen-zi-chuan-de-jie-fa-xiang-jie-zho/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  1. 判断一个整数是否是回文数 [Done]
    9. Palindrome Number (Easy)

  2. 统计二进制字符串中连续 1 和连续 0 数量相同的子字符串个数 [Done]
    696. Count Binary Substrings (Easy)

class Solution {
    public int countBinarySubstrings(String s) {
        
        int i = 0,n = s.length(),last=0,ans = 0,currunt;
        while(i<n){
            char c = s.charAt(i);/注意不能写成 c = s.charAt(i)
            int count = 0;
            while (i<n && s.charAt(i)== c){通过双层循环得到重复的字符数
                i ++;
                count++;
            }
            ans+= Math.min(count,last);
            last = count;
        }
        return ans;
    }
}

数组与矩阵

  1. 把数组中的 0 移到末尾
    283. Move Zeroes (Easy)

  2. 改变矩阵维度
    566. Reshape the Matrix (Easy)

  3. 找出数组中最长的连续 1
    485. Max Consecutive Ones (Easy)

  4. 有序矩阵查找
    240. Search a 2D Matrix II (Medium)

  5. 有序矩阵的 Kth Element
    378. Kth Smallest Element in a Sorted Matrix ((Medium))

  6. 一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数
    645. Set Mismatch (Easy)

  7. 找出数组中重复的数,数组值在 [1, n] 之间
    287. Find the Duplicate Number (Medium)

  8. 数组相邻差值的个数
    667. Beautiful Arrangement II (Medium)

  9. 数组的度
    697. Degree of an Array (Easy)

  10. 对角元素相等的矩阵
    766. Toeplitz Matrix (Easy)

  11. 嵌套数组
    565. Array Nesting (Medium)

  12. 分隔数组
    769. Max Chunks To Make Sorted (Medium)

二分图
  1. 判断是否为二分图
    785. Is Graph Bipartite? (Medium)
拓扑排序
  1. 课程安排的合法性
    207. Course Schedule (Medium)

  2. 课程安排的顺序
    210. Course Schedule II (Medium)

并查集
  1. 冗余连接
    684. Redundant Connection (Medium)

位运算

  1. 统计两个数的二进制表示有多少位不同
    461.Hamming Distance (Easy)

  2. 数组中唯一一个不重复的元素
    136. Single Number (Easy)

  3. 找出数组中缺失的那个数
    268. Missing Number (Easy)

  4. 数组中不重复的两个元素
    260. Single Number III (Medium)

  5. 翻转一个数的比特位
    190. Reverse Bits (Easy)

  6. 不用额外变量交换两个整数 程序员代码面试指南 :P317

  7. 判断一个数是不是 2 的 n 次方
    231. Power of Two (Easy)

  8. 判断一个数是不是 4 的 n 次方
    342. Power of Four (Easy)

  9. 判断一个数的位级表示是否不会出现连续的 0 和 1
    693. Binary Number with Alternating Bits (Easy)

  10. 求一个数的补码
    476. Number Complement (Easy)

  11. 实现整数的加法
    371. Sum of Two Integers (Easy)

  12. 字符串数组最大乘积
    318. Maximum Product of Word Lengths (Medium)

  13. 统计从 0 ~ n 每个数的二进制表示中 1 的个数
    338. Counting Bits (Medium)

算法思想

双指针

  1. 有序数组的 Two Sum
    167. Two Sum II - Input array is sorted (Easy)

  2. 两数平方和
    633. Sum of Square Numbers (Easy)

  3. 反转字符串中的元音字符
    345. Reverse Vowels of a String (Easy)

  4. 回文字符串
    680. Valid Palindrome II (Easy)

  5. 归并两个有序数组
    88. Merge Sorted Array (Easy)

  6. 判断链表是否存在环
    141. Linked List Cycle (Easy)

  7. 最长子序列
    524. Longest Word in Dictionary through Deleting (Medium)

排序

快速选择

用于求解 Kth Element 问题,也就是第 K 个元素的问题。可以使用快速排序的 partition() 进行实现。需要先打乱数组,否则最坏情况下时间复杂度为$ O(N^2) $。

用于求解 TopK Elements 问题,也就是 K 个最小元素的问题。使用最小堆来实现 TopK 问题,最小堆使用大顶堆来实现,大顶堆的堆顶元素为当前堆的最大元素。实现过程:不断地往大顶堆中插入新元素,当堆中元素的数量大于 k 时,移除堆顶元素,也就是当前堆中最大的元素,剩下的元素都为当前添加过的元素中最小的 K 个元素。插入和移除堆顶元素的时间复杂度都为 log2N。

堆也可以用于求解 Kth Element 问题,得到了大小为 K 的最小堆之后,因为使用了大顶堆来实现,因此堆顶元素就是第 K 大的元素。

快速选择也可以求解 TopK Elements 问题,因为找到 Kth Element 之后,再遍历一次数组,所有小于等于 Kth Element 的元素都是 TopK Elements。

可以看到,快速选择和堆排序都可以求解 Kth Element 和 TopK Elements 问题。

  1. Kth Element
    215. Kth Largest Element in an Array (Medium)
桶排序
  1. 出现频率最多的 k 个元素
    347. Top K Frequent Elements (Medium)

  2. 按照字符出现次数对字符串排序
    451. Sort Characters By Frequency (Medium)

荷兰国旗问题

荷兰国旗包含三种颜色:红、白、蓝。

有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列。它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。

  1. 按颜色进行排序
    75. Sort Colors (Medium)

贪心思想

  1. 分配饼干 [Done]
    455. Assign Cookies (Easy)

思路:分别对g和s进行遍历是用是否遍历到最后来判断有没有给g[i]<s[j],由于贪心算法,若有,下次可以继续遍历

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int numOfChildren = g.length, numOfCookies = s.length;
        int count = 0;
        for (int i = 0, j = 0; i < numOfChildren && j < numOfCookies; i++, j++) {
            while (j < numOfCookies && g[i] > s[j]) {
                j++;
            }
            if (j < numOfCookies) {
                count++;
            }
        }
        return count;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/assign-cookies/solution/fen-fa-bing-gan-by-leetcode-solution-50se/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  1. 不重叠的区间个数 [Done]
    435. Non-overlapping Intervals (Medium)
    '注意这里的排序算法的重写!!!
    注意这里的排序算法的重写!!!思路:等价于找最大可连接的区间,按照右端点排序,遍历并更新右节点,判断是否重叠
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0) {
            return 0;
        }
        
        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[1] - interval2[1];
            }
        });

        int n = intervals.length;
        int right = intervals[0][1];
        int ans = 1;
        for (int i = 1; i < n; ++i) {
            if (intervals[i][0] >= right) {
                ++ans;
                right = intervals[i][1];
            }
        }
        return n - ans;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/non-overlapping-intervals/solution/wu-zhong-die-qu-jian-by-leetcode-solutio-cpsb/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  1. 投飞镖刺破气球
    452. Minimum Number of Arrows to Burst Balloons (Medium)
    同样使用右边界排序!!!,这里注意,比较器的编写,如果输入有负数,则不能返回point2【0】-point2【0】,必须分情况讨论,否则负数减去正数等于负数,但是实际上是大于0 的
class Solution {
    public int findMinArrowShots(int[][] points) {
        if (points.length == 0){
            return 0;
        }
        Arrays.sort(points,new Comparator<int[]>() {
            public int compare (int[] point1,int[] point2){
                if (point1[1] > point2[1]) {
                    return 1;
                } else if (point1[1] < point2[1]) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        int ans = 1;
        int right = points[0][1];

        for(int i = 0;i  < points.length;i++){
            if( points[i][0] <= right){ 
                continue;
            }
            right = points[i][1];
            ans+=1;
        }
        return ans;
    }}
  1. 根据身高和序号重组队列
    406. Queue Reconstruction by Height(Medium)

  2. 买卖股票最大的收益
    121. Best Time to Buy and Sell Stock (Easy)

  3. 买卖股票的最大收益 II
    122. Best Time to Buy and Sell Stock II (Easy)

  4. 种植花朵
    605. Can Place Flowers (Easy)

  5. 判断是否为子序列
    392. Is Subsequence (Medium)

  6. 修改一个数成为非递减数组
    665. Non-decreasing Array (Easy)

  7. 子数组最大的和
    53. Maximum Subarray (Easy)

  8. 分隔字符串使同种字符出现在一起
    763. Partition Labels (Medium)

二分查找

  1. 求开方
    69. Sqrt(x) (Easy)

  2. 大于给定元素的最小元素
    744. Find Smallest Letter Greater Than Target (Easy)

  3. 有序数组的 Single Element
    540. Single Element in a Sorted Array (Medium)

  4. 第一个错误的版本
    278. First Bad Version (Easy)

  5. 旋转数组的最小数字
    153. Find Minimum in Rotated Sorted Array (Medium)

  6. 查找区间
    34. Find First and Last Position of Element in Sorted Array

分治

  1. 给表达式加括号
    241. Different Ways to Add Parentheses (Medium)

  2. 不同的二叉搜索树
    95. Unique Binary Search Trees II (Medium)

搜索

BFS
  1. 计算在网格中从原点到特定点的最短路径长度
    1091. Shortest Path in Binary Matrix(Medium)

  2. 组成整数的最小平方数数量
    279. Perfect Squares (Medium)

  3. 最短单词路径
    127. Word Ladder (Medium)

DFS
  1. 查找最大的连通面积
    695. Max Area of Island (Medium)

  2. 矩阵中的连通分量数目
    200. Number of Islands (Medium)

  3. 好友关系的连通分量数目
    547. Friend Circles (Medium)

  4. 填充封闭区域
    130. Surrounded Regions (Medium)

  5. 能到达的太平洋和大西洋的区域
    417. Pacific Atlantic Water Flow (Medium)

Backtracking
  1. 数字键盘组合
    17. Letter Combinations of a Phone Number (Medium)

  2. IP 地址划分
    93. Restore IP Addresses(Medium)

  3. 在矩阵中寻找字符串
    79. Word Search (Medium)

  4. 输出二叉树中所有从根到叶子的路径
    257. Binary Tree Paths (Easy)

  5. 排列
    46. Permutations (Medium)

  6. 含有相同元素求排列
    47. Permutations II (Medium)

  7. 组合
    77. Combinations (Medium)

  8. 组合求和
    39. Combination Sum (Medium)

  9. 含有相同元素的组合求和
    40. Combination Sum II (Medium)

  10. 1-9 数字的组合求和
    216. Combination Sum III (Medium)

  11. 子集
    78. Subsets (Medium)

  12. 含有相同元素求子集
    90. Subsets II (Medium)

  13. 分割字符串使得每个部分都是回文数
    131. Palindrome Partitioning (Medium)

  14. 数独
    37. Sudoku Solver (Hard)

  15. N 皇后
    51. N-Queens (Hard)

动态规划

  1. 回文子字符串个数
    647. Palindromic Substrings (Medium)
斐波那契数列
  1. 爬楼梯
    70. Climbing Stairs (Easy)

  2. 强盗抢劫
    198. House Robber (Easy)

  3. 强盗在环形街区抢劫
    213. House Robber II (Medium)

  4. 信件错排

    题目描述:有 N 个 信 和 信封,它们被打乱,求错误装信方式的数量。

    定义一个数组 dp 存储错误方式数量,dp[i] 表示前 i 个信和信封的错误方式数量。假设第 i 个信装到第 j 个信封里面,而第 j 个信装到第 k 个信封里面。根据 i 和 k 是否相等,有两种情况:

    • i==k,交换 i 和 j 的信后,它们的信和信封在正确的位置,但是其余 i-2 封信有 dp[i-2] 种错误装信的方式。由于 j 有 i-1 种取值,因此共有 (i-1)*dp[i-2] 种错误装信方式。

    • i != k,交换 i 和 j 的信后,第 i 个信和信封在正确的位置,其余 i-1 封信有 dp[i-1] 种错误装信方式。由于 j 有 i-1 种取值,因此共有 (i-1)*dp[i-1] 种错误装信方式。

    综上所述,错误装信数量方式数量为: d p [ i ] = ( i − 1 ) × d p [ i − 2 ] + ( i − 1 ) × d p [ i − 1 ] dp[i]=(i-1) \times dp[i-2] + (i-1) \times dp[i-1] dp[i]=(i1)×dp[i2]+(i1)×dp[i1]

  5. 母牛生产

    程序员代码面试指南-P181
    题目描述:假设农场中成熟的母牛每年都会生 1 头小母牛,并且永远不会死。第一年有 1 只小母牛,从第二年开始,母牛开始生小母牛。每只小母牛 3 年之后成熟又可以生小母牛。给定整数 N,求 N 年后牛的数量。

    第 i 年成熟的牛的数量为: d p [ i ] = d p [ i − 1 ] + d p [ i − 3 ] dp[i] = dp[i-1] + dp[i-3] dp[i]=dp[i1]+dp[i3]

矩阵路径
  1. 矩阵的最小路径和
    64. Minimum Path Sum (Medium)

  2. 矩阵的总路径数
    62. Unique Paths (Medium)

数组区间
  1. 数组区间和
    303. Range Sum Query - Immutable (Easy)

  2. 数组中等差递增子区间的个数
    413. Arithmetic Slices (Medium)

分割整数
  1. 分割整数的最大乘积
    343. Integer Break (Medim)

  2. 按平方数来分割整数
    279. Perfect Squares(Medium)

  3. 分割整数构成字母字符串
    91. Decode Ways (Medium)

最长递增子序列
  1. 最长递增子序列
    300. Longest Increasing Subsequence (Medium)

  2. 一组整数对能够构成的最长链
    646. Maximum Length of Pair Chain (Medium)

  3. 最长摆动子序列
    376. Wiggle Subsequence (Medium)

最长公共子序列
  1. 最长公共子序列
    1143. Longest Common Subsequence
0-1 背包
  1. 划分数组为和相等的两部分
    416. Partition Equal Subset Sum (Medium)

  2. 改变一组数的正负号使得它们的和为一给定数
    494. Target Sum (Medium)

  3. 01 字符构成最多的字符串
    474. Ones and Zeroes (Medium)

  4. 找零钱的最少硬币数
    322. Coin Change (Medium)

  5. 找零钱的硬币数组合
    518. Coin Change 2 (Medium)

  6. 字符串按单词列表分割
    139. Word Break (Medium)

  7. 组合总和
    377. Combination Sum IV (Medium)

股票交易
  1. 需要冷却期的股票交易
    309. Best Time to Buy and Sell Stock with Cooldown(Medium)

  2. 需要交易费用的股票交易
    714. Best Time to Buy and Sell Stock with Transaction Fee (Medium)

  3. 只能进行两次的股票交易
    123. Best Time to Buy and Sell Stock III (Hard)

  4. 只能进行 k 次的股票交易
    188. Best Time to Buy and Sell Stock IV (Hard)

字符串编辑
  1. 删除两个字符串的字符使它们相等
    583. Delete Operation for Two Strings (Medium)

  2. 编辑距离
    72. Edit Distance (Hard)

  3. 复制粘贴字符
    650. 2 Keys Keyboard (Medium)

数学13

素数分解
整除
最大公约数最小公倍数

令: x = 2 m 0 × 3 m 1 × 5 m 2 × 7 m 3 × . . . . x = 2 ^{m0} \times 3^{m1} \times 5 ^ {m2} \times 7^{m3} \times .... x=2m0×3m1×5m2×7m3×.... y = 2 n 0 × 3 n 1 × 5 n 2 × 7 n 3 × . . . . y = 2 ^{n0} \times 3^{n1} \times 5 ^ {n2} \times 7^{n3} \times .... y=2n0×3n1×5n2×7n3×....

则: g c d ( x , y ) = 2 m i n ( m 0 , n 0 ) × 3 m i n ( m 1 , n 1 ) × 5 m i n ( m 2 , n 2 ) × . . . gcd(x,y) = 2 ^{min(m0,n0)} \times 3 ^ {min(m1, n1)} \times 5 ^ {min(m2, n2)} \times ... gcd(x,y)=2min(m0,n0)×3min(m1,n1)×5min(m2,n2)×... l c d ( x , y ) = 2 m a x ( m 0 , n 0 ) × 3 m a x ( m 1 , n 1 ) × 5 m a x ( m 2 , n 2 ) × . . . lcd(x,y) = 2 ^{max(m0,n0)} \times 3 ^ {max(m1, n1)} \times 5 ^ {max(m2, n2)} \times ... lcd(x,y)=2max(m0,n0)×3max(m1,n1)×5max(m2,n2)×...

  1. 生成素数序列
    204. Count Primes (Easy)

  2. 最大公约数

    int gcd(int a, int b) {
       return b == 0 ? a : gcd(b, a % b);
    }
    

    最小公倍数为两数的乘积除以最大公约数。

    int lcm(int a, int b) {
       return a * b / gcd(a, b);
    }
    
  3. 使用位操作和减法求解最大公约数

    对于 a 和 b 的最大公约数 f(a, b),有:

    • 如果 a 和 b 均为偶数,f(a, b) = 2*f(a/2, b/2);
    • 如果 a 是偶数 b 是奇数,f(a, b) = f(a/2, b);
    • 如果 b 是偶数 a 是奇数,f(a, b) = f(a, b/2);
    • 如果 a 和 b 均为奇数,f(a, b) = f(b, a-b);

    乘 2 和除 2 都可以转换为移位操作。

进制转换
  1. 7 进制
    504. Base 7 (Easy)

  2. 16 进制
    405. Convert a Number to Hexadecimal (Easy)

  3. 26 进制
    168. Excel Sheet Column Title (Easy)

阶乘
  1. 统计阶乘尾部有多少个 0
    172. Factorial Trailing Zeroes (Easy)
字符串加法减法
  1. 二进制加法
    67. Add Binary (Easy)

  2. 字符串加法
    415. Add Strings (Easy)

相遇问题
  1. 改变数组元素使所有的数组元素都相等
    462. Minimum Moves to Equal Array Elements II (Medium)
多数投票问题
  1. 数组中出现次数多于 n / 2 的元素
    169. Majority Element (Easy)
其它
  1. 平方数
    367. Valid Perfect Square (Easy)

  2. 3 的 n 次方
    326. Power of Three (Easy)

  3. 乘积数组
    238. Product of Array Except Self (Medium)

  4. 找出数组中的乘积最大的三个数
    628. Maximum Product of Three Numbers (Easy)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值