Contents

算法题记录

Contents

查找

有序数组的二分查找

链接

包含重复元素有序数组的二分查找

链接

猜数字大小

链接

在排序数组中查找元素的第一个和最后一个位置

链接

搜索插入位置

链接

搜索旋转排序数组

链接

搜索旋转排序数组2

链接

寻找排序数组中的最小值

链接

x的平方根

链接

排序

基础排序算法

链接

合并两个有序数组

链接

删除数组中的重复元素

链接

移除元素

链接

移动零

链接

数组中出现次数大于一半的数字

链接

合并排序数组

链接

寻找第K大的元素

链接

最小的K个数(topK问题)

链接

重建二叉树

链接

最大二叉树

链接

合并二叉树

链接

二叉搜索树中的搜索

链接

验证二叉搜索树

链接

二叉搜索树的绝对值之差

链接

二叉搜索树的众数

链接

二叉树的最近公共祖先

链接

二叉搜索树的最近公共祖先

[链接](二叉搜索树的最近公共祖先 - 二叉搜索树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com))

二叉搜索树的插入操作

链接

二叉搜索树的删除操作

链接

二叉搜索树的修剪

链接

将二叉树转换为累加树

链接

翻转二叉树

链接

二叉树的前序遍历

链接

二叉树的中序遍历

链接

二叉树的后序遍历

链接

二叉树的层序遍历

链接

二叉树的层序遍历2

链接

二叉树的之字形层序遍历

链接

N叉树的层序遍历

链接

从上到下打印二叉树

链接

二叉搜索树中第k小的元素

链接

将有序数组转换为二叉搜索树

链接

将有序链表转换为二叉搜索树

链接

二叉树的右视图

链接

二叉树的层平均值

链接

二叉树的层最大值

链接

填充每个节点的下一个右侧节点指针

链接

树的子结构

链接

另一棵树的子树

链接

对称二叉树

链接

相同的树

链接

二叉树的最大深度

链接

N叉树的最大深度

链接

二叉树的最小深度

链接

完全二叉树的节点个数

链接

平衡二叉树

链接

左叶子之和

链接

找树左下角的值

链接

路径总和

链接

回溯算法

全排列

链接

全排列2

链接

子集

链接

子集2

链接

组合

链接

组合总和

链接

小结

1.

全排列:结果是有序的,即[1,2,3]和[2,1,3]是两个不同的结果

组合:结果是无序的,即[1,2,3]和[2,1,3]是相同的结果

那么这两者的处理方式分别是什么呢:

针对组合问题,具体的做法是:每一次搜索的时候设置 下一轮搜索的起点 begin

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#对于全排列问题
    class  Solution {
    public List<List<Integer>>  permute(int[] nums){
        int len= nums.length;
        List<List<Integer>> res=new ArrayList<>();
        if (len==0) return res;

        Deque<Integer> path=new ArrayDeque<>(len);
        boolean[] used=new boolean[len];
        dfs(nums,len,0,path,used,res);
        return res;
    }
   
    private void dfs(int[] nums, int len, int depth, Deque<Integer> path, boolean[] used, List<List<Integer>> res) {
        if (depth==len) {
            res.add(new ArrayList<>(path));
            return;
        }

        for (int i=0;i<len;i++){//注意这里是i=0,表示每一次遍历都是遍历整个数组中的元素
            if (!used[i]){
                path.add(nums[i]);
                used[i]=true;

                dfs(nums, len, depth+1, path, used, res);

                used[i]=false;
                path.removeLast();
            }
        }
    }
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#组合问题
    class Solution {
    public List<List<Integer>> combine(int n, int k) {

        List<List<Integer>> res = new ArrayList<>();
        if (n == 0) return res;
        int[] nums = new int[n];//先将其转换为数组
        for (int i = 1; i <= n; i++) {
            nums[i - 1] = i;
        }


        Deque<Integer> path = new ArrayDeque<>();
//采用深度优先遍历的方式,begin表示从剩下的元素中挑选元素,例如在[1,2,3,4]中先选1后,只能够在[2,3,4]中挑选元素
        dfs(nums, 0, k, 0, path, res);
        return res;

    }

    private void dfs(int[] nums, int depth, int k, int begin, Deque<Integer> path, List<List<Integer>> res) {
        if (depth == k) {//depth表示path中的元素个数
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i = begin; i < nums.length; i++) {//使用begin设置下一轮的搜索起点,这样能保证解是无序的

            path.add(nums[i]);

            dfs(nums, depth + 1, k, i + 1, path, res);//因为使用过的元素是不能够再次使用的,所以是i+1;
            //如果使用过的元素是能够再次使用的,则为i

            path.removeLast();

        }
    }
}

2.

对于子集中

可以对每一层选与不选元素进行分类,最后的叶子节点即为所求结果

3.

对于全排列2中,因为数组存在重复元素,为了删除重复的结果集,所以需要采用剪枝操作。

大体的思想就是

通过 i>0&&nums[i]==nums[i-1]&&!used[i-1] 可以让同一层级,不出现相同的元素。即 1 /
2 2 这种情况不会发生 但是却允许了不同层级之间的重复即: /
5 5 例2 1 / 2 这种情况确是允许的 / 2

对于子集2中,数组中的元素存在重复元素,同样的通过i>begin&&nums[i]==nums[i-1]来保证同一层中不出现重复元素

对于组合总和问题2,其实最大的不同也就是元素存在重复元素,解决方式同样是i > begin && candidates[i] == candidates[i - 1]来保证同一层不出现重复元素。

这里可以看出

  • 如果解的无序的,就使用begin变量来设置下一轮搜索起点
  • 如果数组中存在重复元素,就利用类似i > begin && candidates[i] == candidates[i - 1]的方式来保证同一层不出现重复元素。以此进行剪枝操作。

排列序列

链接

二叉树的所有路径

链接

二叉树中和为某一值的路径

链接

递增子序列

[链接](递增子序列 - 递增子序列 - 力扣(LeetCode) (leetcode-cn.com))

划分为k个相等的子集

链接

字符串的排列

链接

动态规划

零钱兑换

链接

爬楼梯

链接

使用最小花费爬楼梯

链接

将数字翻译成字符串

链接

解码方法

链接

完全平方数

链接

整数拆分

链接

单词拆分

链接

组合总和4

链接

零钱兑换2

链接

分割等和子集

链接

最后一块石头的重量

链接

目标和

链接

一和零

链接

连续子数组的最大和

链接

连续子数组的最大乘积

链接

最长连续递增子序列

链接

最长递增子序列

链接

最长递增子序列的个数

链接

无重叠区间

链接

最长数对链

链接

礼物的最大价值

链接

打家劫舍

链接

打家劫舍2

链接

打家劫舍3

链接

不同路径

链接

不同路径2

链接

买卖股票的最佳时机

链接

买卖股票的最佳时机2

链接

买卖股票的最佳时机含冷冻期

链接

买卖股票的最佳时机含手续费

链接

最长公共子序列

链接

最长公共字符列2

链接

最长公共子序列3

链接

回文子串

链接

最长回文子串

链接

通配符匹配

链接

链表

反转链表

链接

反转链表2

链接

K 个一组翻转链表

链接

删除链表的节点

链接

合并两个排序的链表

链接

合并K个已排序链表

链接

链表中倒数第k个节点

链接

两个链表的第一个公共节点

链接

复杂链表的复制

链接

从尾到头打印链表

链接

二叉搜索树与双向链表

链接

有序链表转换成二叉搜索树

链接

LRU实现

链接

链表相加

链接

链表中是否存在环

链接

环状链表2

链接

删除链表的倒数第 N 个结点

链接

链表排序

链接

字符串

字符串中的最长无重复子串

链接

有效的括号字符串

链接

大数加法

链接

反转字符串

链接

栈和队列

两个栈实现队列

链接

包含min函数的栈

链接

滑动窗口

和为S的连续正整数

链接

和为S的两个数字

链接

两数之和

链接

三数之和

链接

四数之和

链接

盛最多水的容器

链接

容器盛水问题

链接

其他

螺旋矩阵

链接

矩阵中的路径

链接

整数反转

链接

二进制数反转

链接

二进制中1的个数

链接

剑指

数组中的重复元素

链接

二维数组中的查找

链接

替换空格

链接

从尾到头打印链表

链接

重建二叉树

链接

两个栈实现队列

链接

斐波那契数列

链接

旋转数组中的最小值💡

链接

矩阵中的路径

链接

机器人的运动范围

链接

剪绳子

链接

剪绳子2

链接

二进制中1的个数

链接

数值的整数次方

链接

打印从1到最大的n位数🎈

链接

删除链表的结点

链接

正则式匹配🎈

链接

表示数值的字符串🎈

链接