万物的算法日记|第二天

笔者自述:

一直有一个声音也一直能听到身边的大佬经常说,要把算法学习搞好,一定要重视平时的算法学习,虽然每天也在学算法,但是感觉自己一直在假装努力表面功夫骗了自己,没有规划好自己的算法学习和总结,因为后半年也该找实习了,所以每日的算法题要进行恶补,勤能补拙,因此有了这一个算法日记系列;

必读: 大佬你好,感谢您的阅读,这篇文章是我的算法笔记,方便我每日回顾;
为了不耽误您的时间,我把本篇日记的考点方向和算法知识总结列出来,如果对您有需要要就向下继续阅读

也希望对您有帮助,和您一起通关算法!致谢

万物的算法日记|第二天_第1张图片
算法语言:java
题目来源:力扣–书本–图解算法数据结构,可以在力扣中搜索相关题名找到更多解法和大神方法
本文知识点汇总:

  1. ArrayList和LInked两个列表的区别
    底层不同:ArrayLIst和LInked: ArrayList底层是数组实现的,可以快速访问元素,而LinkedList需要从头或尾部进行遍历;对于删除元素时,LInkedList可以更快的删除元素,而ArrayLIst相对麻烦。针对不同情况进行选择;
    适用场景不同: 对于频繁增删的使用LinkedLIst;对于随机访问和数据量较小的知识及顺序访问列表中的元素,使用ArrayList、

  2. 位运算
    关于异或的规则:a^a =0, a^0 = a,;同时满足异或交换律,可以用于三次异或来进行交换两个数的值abc =acb

  3. Arrays中自带求和和排序方法
    使用Arrays内置的求和公式,Arrays.stream(inteferface{}).sum() 求和 ,Arrays.sort() 排序 但是相对时间复杂度会上升


  4. 栈: 什么是栈? 先进后出,一种线性数据结构。
    为什么链表可以用来表示栈 ??链表表示栈可以动态地添加和删除元素,更加灵活和强大,适合频繁的删除和添加元素场景。LInkedList和ArrayLIst都适合来表示栈,一般常用LinkedList来表示栈,ArrayList底层是一个数组,LinkedList底层是链表,更适合一些。同时链表中自带的方法,例如:addFirst,offerFirst,removeLast,pollLast方法组合可以很好的将元素push和pop进出栈。就时间复杂度而言,栈的入栈push和出栈pop操作都是O(1),同时使用两个栈来进行相互辅助,栈a作为存放元素,栈b作为存放非严格排序的元素,可以找到min值,就在栈b中

  5. 队列
    什么是队列?先进先出,一种特殊的线性表
    使用两个栈来实现队列的思路:两个栈S1和S2,一个用于插入元素(入队操作),一个用于删除元素(出队操作)

详细可针对具体题目具体分析~~

文章目录

  • 杨辉三角
  • 缺失数字
  • 剑指Offer09.用两个栈实现队列
  • 剑指Offer30. 包含min函数的栈

杨辉三角

万物的算法日记|第二天_第2张图片

class Solution {
   public List<List<Integer>> generate(int numRows) {
       List<List<Integer>> list = new ArrayList<>();
       List<Integer> res = new ArrayList<>();
       // 排除为0条件
       if(numRows == 0) return list;
       //将第一行添加到列表中
       res.add(1);
       list.add(res); 
       //从第二行开始进行遍历循环 i表示行数,j表示索引位置
       for(int i =1;i<numRows;i++){
           List<Integer> row = new ArrayList<>();
           //首先在该行第一个位置加入1
           row.add(1);
           //因为 该行增添了一个1,该数向后挪动了一位,所以该数和为上一层的j和j+1组成
           for(int j=0;j<list.get(i-1).size()-1;j++){
               row.add(list.get(i-1).get(j)+list.get(i-1).get(j+1));
           }
           //在该行最后一位添上1,一位我的j的范围是取到倒数第二位
           row.add(1);
           list.add(row);
       }
       return list;
    }
}

思路 && 学到的知识点:

  1. 首先是列表形式的选择,分别是ArrayList和LinkedList;
    区别:ArrayList 底层是数组实现,利于快速访问元素,LinkedList需要从头或者尾部开始遍历,没有ArrayList方便,但是在删除元素时,LInkedList更方便;、
    使用场景:对于频繁进行插入删除用lInkedList,对于随机访问,或者数据量较小的且只是顺序访问列表中的元素,使用ArrayList。
  2. 思路可以一步一步分析给出的代码,写的很清晰了步骤

缺失数字

万物的算法日记|第二天_第3张图片
代码:

 // 位运算 
   public int missingNumber(int[] nums){
        int xor =0;
        for(int i=0;i<nums.length;i++){
            xor ^= nums[i] ^i;
        }
        return xor^ nums.length;
    }
//求和解法+
    public int missingNumber(int[] nums){
        int sum =0;
        int length = nums.length;
        int sum1=Arrays.stream(nums).sum();
        for(int i =1;i<=length;i++){
            sum +=i;
        }
        return sum-sum1;
    }

学到的知识:

  1. 位运算操作:异或运算: 相同的数异或等于0;一个数和0异或为它自己;a ^ b ^ c = a ^ c ^b 具有交换律的性质
  2. 使用Arrays内置的求和公式,Arrays.stream(inteferface{}).sum() 求和

剑指Offer09.用两个栈实现队列

万物的算法日记|第二天_第4张图片
代码:

class CQueue {
    LinkedList<Integer> A,B;
    public CQueue() {
        A = new LinkedList<Integer>();
        B = new LinkedList<Integer>();
    }
    public void appendTail(int value) {
        A.addLast(value);
    }
    public int deleteHead() {
        if(!B.isEmpty()) return B.removeLast();
        if(A.isEmpty()) return -1;
        while(!A.isEmpty()){
            B.addLast(A.removeLast());
        }
        return B.removeLast();
    }
}

学到的知识:

  1. 栈: 什么是栈? 先进后出,一种线性数据结构。
    为什么链表可以用来表示栈 ??链表表示栈可以动态地添加和删除元素,更加灵活和强大,适合频繁的删除和添加元素场景。LInkedList和ArrayLIst都适合来表示栈,一般常用LinkedList来表示栈,ArrayList底层是一个数组,LinkedList底层是链表,更适合一些。同时链表中自带的方法,例如:addFirst,offerFirst,removeLast,pollLast方法组合可以很好的将元素push和pop进出栈。
  2. 队列: 什么是队列?先进先出,一种特殊的线性表
    使用两个栈来实现队列的思路:两个栈S1和S2,一个用于插入元素(入队操作),一个用于删除元素(出队操作)
    流程: 在插入元素时,将元素push到s1栈中,在删除元素时,将s1中的所有元素都弹出来到s2中,然后将s2的栈顶元素出栈并返回,当s1和s2都为空时,则说明队列是空了

剑指Offer30. 包含min函数的栈

万物的算法日记|第二天_第5张图片
代码:

    //难点:如何降低时间复杂度,因为 寻找最小元素 需要遍历整个栈,时间复杂度是O(n),
    //因为普通栈的出栈和入栈的复杂度是 O(1),所以可以借助栈来进行降低时间复杂度
    Stack<Integer> A,B;
    public day6_13_4(){
        A = new Stack<>();
        B = new Stack<>();
    }
    public void push(int x){
        A.add(x);
        if(B.empty() || B.peek() >= x){
            B.add(x);
        }
    }
    public void pop(){
        if (A.pop().equals(B.peek())){
            B.pop();
        }
    }
    public int top(){
        return A.peek();
    }
    public int min(){
        return B.peek();
    }

学到的知识点:

  1. 就时间复杂度而言,栈的入栈push和出栈pop操作都是O(1),同时使用两个栈来进行相互辅助,栈a作为存放元素,栈b作为存放非严格排序的元素,可以筛选出。

你可能感兴趣的:(万物的算法日记,算法,数据结构,链表)