跟着公众号刷leetcode算法

https://github.com/youngyangyang04/leetcode-master

数组部分

2020.9.8

  • 搜索插入位置
    一道简单的二分题目,提到有序数组,就可以用二分试一试。我目前用的是C++,在评论区看到一个代码,
    return lower_bound(nums.begin(),nums.end(),target) - nums.begin();
    
    lower_bound适用于排过序的数组,且底层算法的时间复杂度为O(n)
    与二分查找相关的三个函数,函数内部使用二分查找实现
    #include 前提:有序数组
    1️⃣lower_bound(起始地址,结束地址,查找元素) 左闭右开的区间,查找第一个大于等于指定元素的位置(第一个可插入的位置),若无,则返回end(超界)
    2️⃣upper_bound(起始地址,结束地址,查找元素)左闭右开,查找第一个大于指定元素的位置(最后一个可插入的位置),若无,则返回end(超界)
    3️⃣binary_search(起始地址,结束地址,查找元素)左闭右开区间,返回bool值
  • 移除元素
    双指针方法,没什么特别的
  • 删除排序数组中的重复项
    同上题,双指针法
  • 长度最小的子数组
    双指针或者滑动窗口法,两个指针start、end,end遍历整个数组,求以end为最后一个元素的满足子数组元素之和大于s的数组最小长度,start随着滑动窗口内元素之和进行调整,时间复杂度为O(n)
    还有一个O(nlogn)的算法,待补(❓)可能有什么特殊的方法需要学习吧

2020.9.10

  • 螺旋矩阵 2
    明明是一道很简单的模拟题,被我做出了高考数学最后一个大题的感觉,说到底还是细节把握的不好,编程习惯可能也不好,总之就是都不好,要多练练啊,脑子想的和动手编程的结果真的不一样。
    我犯的几个错误:
  1. 题目输出要求的是vector,我在定义vector的时候没有初始化,后面直接采用数组的形式进行赋值,oh~
  2. for循环中用于控制循环次数的变量i,我保留了它,用到下一个for循环中,却忘记了上一个循环是因为i不满足循环条件了才退出的,把i当成是符合条件的最后一个数值进行运算,导致数据越界,shift!
    基本的思路就是一圈一圈填充,我是用每一圈的宽度来控制计算坐标值,在题解区看到有人定义四个变量来控制边界,真的很简洁,代码也很简洁,需要学习~

class Solution {
    public int[][] generateMatrix(int n) {
        int l = 0, r = n - 1, t = 0, b = n - 1;
        int[][] mat = new int[n][n];
        int num = 1, tar = n * n;
        while(num <= tar){
            for(int i = l; i <= r; i++) mat[t][i] = num++; // left to right.
            t++;
            for(int i = t; i <= b; i++) mat[i][r] = num++; // top to bottom.
            r--;
            for(int i = r; i >= l; i--) mat[b][i] = num++; // right to left.
            b--;
            for(int i = b; i >= t; i--) mat[i][l] = num++; // bottom to top.
            l++;
        }
        return mat;
    }
}

2020.9.11

大清早来,我决定先把“螺旋矩阵2”再写一遍,是烦躁的一天还是开心的一天就看它的了——早上比较清醒,一遍过,开心~开始科研

  • 二维数组并不是n*m的连续地址空间组成的


    跟着公众号刷leetcode算法_第1张图片
    二维数组
  • 忽然看到了一个熟悉的题目就做了一下 编辑距离
    一发A,感觉自己dp基础知识掌握的还不错,这题有点像最长公共子串的长度
  • 必须掌握的数组理论知识

2020.9.12

今日份睡觉和科研任务比较重

  • 四数之和 和之前做过的三数之和几乎完全一样
  • 环形链表 II 双指针法
    环形列表需要使用双指针法,两指针相遇则存在环,这题可能不需要数学推导,知道快慢指针由于速度不同终将相遇即可,而对于 II 这道题需要判断环的入口位置,我虽然能想到双指针,但不知道需要数学推导出相遇位置与入口位置之间的关系(吃一堑长一智,我觉得在做题的时候,如果知道了大体的方法,但方法的结束点和最终要达成的目的看似没什么联系,先想想贪心算法蒙一下,实在不行,看看有没有什么数学上的值的关系,当时我能手动模拟一下也好啊,说不定就发现了,后悔)
    跟着公众号刷leetcode算法_第2张图片
    模拟图

    官方题解的公式我觉得有点问题,下面是我的公式:
    2(F+a)=F+n(a+b)+a (n表示快指针比慢指针多走的圈数)
    F=n(a+b)-a=(n-1)(a+b)+b
    也就是说无论n取何值,从head出发的速度为1的指针和从相遇点出发的速度为1的指针,一定会在入口处相遇
/*写给自己:注意fast和low的起点必须一样,和之前的程序有一点小小的不同,之前不用考虑是否起点一致,只要能相遇就行
在这里如果起点不一致的话,不能同时出发然后相遇于入口点,需要添加一些常数来补充*/
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head==NULL || head->next==NULL) return NULL;
        ListNode* low=head;
        ListNode* fast=head;
        
        while(fast!=NULL && fast->next!=NULL){
            
            low=low->next;
            fast=fast->next->next;
            if(fast==low) break;
        }

        if(fast==NULL|| fast->next==NULL) return NULL;

        ListNode* p=head;
        while(p!=low){
            p=p->next;
            low=low->next;
        }
        return low;
    }
};

2020.9.15

这几天因为科研上的一些问题,没有做题,今天抽出点时间,准备刷leetcode的数组分类下的题目,就从简单的开始吧。

  • 转置矩阵 行列交换
  • 主要元素
    摩尔投票法(默认存在众数的情况下) 本题最后要加上一个循环来进行验证
  • 有序数组的平方
    一定不要忽略“有序”这个词,使用双指针法
  • 三个数的最大乘积
    贪心,排序后,最大乘积只可能出现在两种情况下
  • 存在连续三个奇数的数组
  • 存在重复元素 II
    是一个处理不好就会超时的题,O(nlogn)排序后就会超时
    解决方法:k的滑动窗口,Set(hashset)
    ✨总结:
    题型:查找是否存在值为x的元素,可能还需要确定它的位置
    方法:map——我目前做的题不多,我认为用到map的地方都有一个相似的地方:与数组相比,map将数组的值作为索引,而将数组的下标作为map的数值,这样查找某个元素的速度就会很快。
    不能简单的用数组来实现,因为测试样例中可能有负值,例如[-1,-1]
  • 种花问题
    模拟;另一个思路,数连续0的位置,然后直接计算之间可以放多少花
  • 翻转图像 听我的,直接翻
  • 找出井字棋的获胜者 模拟

2020.9.18

  • ✨合并两个有序数组 双指针从后往前
  • 统计好三元组
  • 数组序号转换
  • 拼写单词 使用数组会比hash更快一些
  • 二维网格迁移
  • 访问所有点的最小
  • 斐波那契数
    ✨矩阵幂求解这种方法需要学习一下

2020.9.21

  • ✨所有奇数长度子数组的和
    思维方式很重要,考虑如何才能组成一个长度为奇数的数组

2020.9.24

  • 至少是其他数字两倍的最大数 除法的时候小心除数可能为0,应该转成乘法
  • 剑指 Offer 04. 二维数组中的查找 旋转一下就像一棵二叉搜索树
  • 第 k 个缺失的正整数
    没什么特别的就是让我体会到了c好快,c++写的时间击败4%,c写的击败100%
    另一个方法:二分查找
  • 按奇偶排序数组 II 内存可以为O(1)
  • 解压缩编码列表
  • 两数之和 II - 输入有序数组
  • 移动零

2020.9.27

  • 数组的度
  • 重塑矩阵
  • 将每个元素替换为右侧最大元素

2020.9.28

美丽的早晨从刷几道题开始;用java写几道简单题

  • 一维数组的动态和
  • 有多少小于当前数字的数字
  • 去掉最低工资和最高工资后的工资平均值
  • 面试题 17.04. 消失的数字 有一个很巧妙的方法,希望我下次可以想起来
  • 方阵中战斗力最弱的 K 行
  • 重新排列数组
  • 最小绝对差
  • 玩筹码
  • 缀点成线

2020.9.29

  • 查找常用字符
  • 和为零的N个唯一整数

2020.9.30

  • 缺失数字
  • 公平的糖果交换
  • 查询后的偶数和
  • 杨辉三角
  • 杨辉三角 II

数组的解题方法

1、暴力再寻求优化
2、二分(或者需要先自行排序,再使用二分)
3、递归
4、(窗口方法)
5、双指针法(快慢指针法,两个指针的前进速度不同,前进的判断条件不同,在一个for循环中完成两个for循环的工作量) 考虑同时从左边开始,同时从右边开始,一左一右开始,都想一遍,不要限制思维
6、摩尔投票法
(随着刷题持续增加)
7、hash或者数组,更换索引和数值的关系
8、贪心方法:思考如何从当前元素出发,构造出符合题目条件的样子,在这个过程中,再考虑把其他的方法(排列组合等)用进来

hash:

  • 数组拆分 I
  • 数组的相对排序
    set: 用空间换时间,查看某个元素是否在集合内
  • 公平的糖果交换

你可能感兴趣的:(跟着公众号刷leetcode算法)