代码随想录总结

记录的都是我不清楚的知识点,仅供自己参考。

一、数组

理论基础

二维数组在内存空间地址中的连续性:C++连续,Java不连续
Java定义二维动态数组(总是记不住):ArrayList<List<Integer>> list = new ArrayList<List<Integer>>();

在这里插入图片描述

二分法

关键点:左闭右开区间还是左闭右闭区间。while循环里是合法区间,循环时不包含上一次循环的区间。

  • C++求数组长度:(vector类数组)
    • 一维数组:arr.size()
    • 二维数组行长度:arr.size()
    • 二维数组列长度:arr[0].size()
  • Java求数组长度:
    • 一维数组:arr.length 注:不带()
    • 二维数组行长度:arr.length
    • 二维数组列长度:arr[i].length

移除元素

C++移除数组元素库函数(刷题时不要直接用库函数):
erase() 时间复杂度:o(n)

双指针法移除数组元素:https://www.bilibili.com/video/BV12A4y1Z7LP/?vd_source=5c915cf57c18c90b48105ad42b2a7ef9&t=368.0

// 时间复杂度:O(n)
// 空间复杂度:O(1)
class Solution {
    
    
public:
    int removeElement(vector<int>& nums, int val) {
    
    
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
    
    
            if (val != nums[fastIndex]) {
    
    
                nums[slowIndex++] = nums[fastIndex];
            }
        }
        return slowIndex;
    }
};

数组常用函数:
数组排序:Arrays.sort(arr, new Comparator(){})
数组转换成字符串:Arrays.toString(arr)

二、链表

移除链表元素

注:C++在删除链表元素时,需要对删除元素进行手动释放:delete()

头结点与中间节点的删除方式不一样。

头结点删除方式:head = head->next;
中间节点删除方式:p->next = q->next;

所以有两种方法删除。
法一:先删除头结点,再删除中间节点

class Solution {
    
    
public:
    ListNode* removeElements(ListNode* head, int val) {
    
    
        // 删除头结点
        while (head != NULL && head->val == val) {
    
     // 注意这里不是if
            ListNode* tmp = head;
            head = head->next;
            delete tmp;
        }

        // 删除非头结点
        ListNode* cur = head;
        while (cur != NULL && cur->next!= NULL) {
    
    
            if (cur->next->val == val) {
    
    
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            } else {
    
    
                cur = cur->next;
            }
        }
        return head;
    }
};

法二:额外增加一个数值为空的头结点指向当前头结点,将头结点与中间节点的删除方式统一起来。

class Solution {
    
    
public:
    ListNode* removeElements(ListNode* head, int val) {
    
    
        ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
        dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
        ListNode* cur = dummyHead;
        while (cur->next != NULL) {
    
    
            if(cur->next->val == val) {
    
    
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            } else {
    
    
                cur = cur->next;
            }
        }
        head = dummyHead->next;
        delete dummyHead;
        return head;
    }
};

Java链表

创建节点结构体

public class ListNode<E> {
    
    
    public E val;
    public ListNode next;
    ListNode(E x)
    {
    
    
        this.val = x;
        this.next = null;
    }
}

链表操作

package Link;

import java.util.LinkedList;

public class MyLinkedList<E> {
    
    
    //头结点
    public ListNode<E> head = null;

    //头插法插入新节点
    public void addFirst(E data){
    
    
        ListNode<E> node = new ListNode<>(data);
        if(head==null){
    
    
            head = node;
        }else{
    
    
            node.next = head;
            head = node;
        }
    }

    //尾插法插入新节点
    public void addLast(E data){
    
    
        ListNode<E> node = new ListNode<>(data);
        if(head==null){
    
    
            head = node;
        }else{
    
    
            ListNode<E> p = head;
            while(p.next!=null){
    
    
                p = p.next;
            }
            p.next = node;
        }
    }

    //任意位置插入新节点
    public void addAny(E data, int num){
    
    
        //判断num范围
        if(num<0||num>this.size()){
    
    
            //Java异常还没学,学完了修改
            System.out.println("异常,插入索引错误");
        }else if(num==0){
    
    
            ListNode<E> q = new ListNode<>(data);
            q.next = head;
            head = q;
        }else{
    
    
            ListNode<E> q = new ListNode<>(data);
            ListNode<E> p = head;
            while(num--!=1){
    
    
                p = p.next;
            }
            q.next = p.next;
            p.next = q;
        }
    }

    //打印链表
    public void display(){
    
    
        //链表空
        if(head==null){
    
    
            System.out.println("链表为空");
        }
        ListNode<E> p = head;
        while(p!=null){
    
    
            System.out.println(p.val);
            p = p.next;
        }
    }

    //判断节点是否存在
    public boolean isInstance(E data){
    
    
        ListNode<E> p = head;
        while(p!=null){
    
    
            if(p.val==data){
    
    
                return true;
            }
            p = p.next;
        }
        return false;
    }

    //查找节点,返回下标
    public int find(E data){
    
    
        if(this.isInstance(data)){
    
    
            ListNode<E> p = head;
            int count = 0;
            while(p!=null){
    
    
                if(p.val==data){
    
    
                    return count;
                }
                count++;
                p = p.next;
            }
        }
        return -1;
    }

    //删除第一个关键字为data的链表节点并返回元素
    public void remove(E data){
    
    
        ListNode<E> p = head;
        //头结点需特判
        if(head!=null&&head.val==data){
    
    
            head = head.next;
            return;
        }
        while(p!=null&&p.next!=null){
    
    
            if(p.next.val==data){
    
    
                p.next = p.next.next;
                return;
            }
            p = p.next;
        }
    }

    //删除所有关键字为key的节点
    public void removeAll(E data){
    
    
        ListNode<E> dummyHead = new ListNode<>(data);
        dummyHead.next = head;
        ListNode<E> p = dummyHead;
        while(p.next!=null){
    
    
            if(p.next.val==data){
    
    
                p.next = p.next.next;
            }else{
    
    
                p = p.next;
            }
        }
        head = dummyHead.next;
    }

    //删除指定位置节点
    public E removeAt(int num){
    
    

        //判断num范围
        if(num<0||num>this.size()-1){
    
    
            System.out.println("索引异常");
            return null;
        }else if(num==0){
    
    
            ListNode<E> q = head;
            head = head.next;
            return q.val;
        }else {
    
    
            ListNode<E> p = head;
            while (num-- != 1) {
    
    
                p = p.next;
            }
            ListNode<E> q = p.next;
            p.next = p.next.next;
            return q.val;
        }
    }

    //获取指定位置节点元素
    public E get(int num){
    
    
        if(num<0||num>this.size()-1){
    
    
            System.out.println("索引异常");
            return null;
        }else {
    
    
            ListNode<E> p = head;
            while (num-- != 0) {
    
    
                p = p.next;
            }
            return p.val;
        }
    }

    //链表长度
    public int size(){
    
    
        int count = 0;
        ListNode p = head;
        while(p!=null){
    
    
            p = p.next;
            count++;
        }
        return count;
    }

    //清空链表
    public void clear(){
    
    
        //链表本身为空
        head = null;
    }
}

测试

package Link;
import java.util.LinkedList;

public class main {
    
    
    public static void main(String[] args) {
    
    
        MyLinkedList<Integer> ll = new MyLinkedList<>();
//        ll.display();
        ll.addLast(0);
        ll.addLast(1);
        ll.addLast(2);
//        ll.display();
        System.out.println(ll.isInstance(100));
        ll.addAny(100, 3);
        System.out.println(ll.isInstance(100));
        ll.display();
        System.out.println("size:"+ll.size());
        System.out.println(ll.find(101));
        System.out.println("-------------------");
        ll.remove(100);
        ll.remove(0);
        ll.display();
        System.out.println("-----------------");
        ll.addLast(0);
        ll.addLast(0);
        ll.addLast(0);
        ll.addLast(0);
        ll.addLast(1);
        ll.display();
        System.out.println("-----------------");
        ll.removeAll(100);
        ll.display();
        System.out.println("-----------------");
        System.out.println("删除的是:"+ll.removeAt(5));
        ll.display();
        System.out.println("-----------------");
        System.out.println(ll.get(0));
        System.out.println("-----------------");
        ll.clear();
        ll.display();
    }

}

三、哈希表(这章内容都不太会,还是看看随想录原文)

用哈希法的前提:元素是否出现过
Java注意事项:

  • 数组默认初始化是有值的,不是随机数,是0
  • 获取数组长度:arr.length
  • 获取字符串长度:str.lenrth()
  • Java里的true/false不能用1/0表示,比如while(1)不可以这么写,会报错。
  • Java字符数组转换为字符串:String.valueOf()

四、字符串

Java

Java的字符串不能原地修改,可以重新创建一个StringBuilder,StringBuilder可以修改

  • StringBuilder常用函数:

sb.append(" aaa") 添加字符串
sb.reverse() 字符串反转
sb.toString() 把StringBuilder类型转换为String类型
sb.charAt(i) 返回第i个位置的字符
sb.setCharAt(i, u) 将第i个位置的字符设置为u

//字符转换为字符串
String str = String.valueOf(Char);
//字符串转换为字符数组
char[] c = s.toCharArray();
//字符数组转换为字符串

  • 分割字符串:substring()
String s = "abcde";
String str = s.substring(0,2);//左闭右开,此时str的值为ab

C++

不像Java,C++字符串可以用数组索引获取字符串中的字符,也可以修改字符串中的字符
扩充字符串大小:s.resize(k) k表示字符串长度

五、KMP算法

KMP算法这块真是太头大了!刚接触这个概念的小白真是怎么听也听不明白,感觉视频里有很多细节都没有讲清楚,看这个:https://www.cnblogs.com/dusf/p/kmp.html

六、栈与队列

Java栈:

  • 参考:https://www.jianshu.com/p/01192de8c21a
  • 栈继承自Vector,vector与ArrayList都继承自List。
  • 导包:import java.util.Stack;
  • 创建对象:Stack<> st = new Stack<>();
  • 常用函数:push(); pop(); isEmpty(); peek();(peek是获取栈顶元素值,元素不出栈)
  • 注:Java的栈继承自Vector,并没有对插入删除做出限制,这样破坏了栈的封装结构(参考https://zhuanlan.zhihu.com/p/164795238)。

Java队列

  • 参考:https://www.jianshu.com/p/7a86c56c632b
  • 导包:import java.util.Queue;
  • 定义队列:LinkedList<String> queue;
  • 实现队列:queue = new LinkedList<String>();
  • 常用方法:
    • offer()/add(); 添加元素,添加成功返回true
    • poll()/remove(); 删除队头元素并返回值,删除失败返回null
    • peek(); 返回队头元素
    • size(); 返回队列元素个数
    • isEmpty(); 判断是否为空

Java双端队列(存疑)

Java优先级队列

优先级队列会把队列内元素做一个排序,按一定的优先级顺序出队列。(原理没细看,可以看看源码)

  • 参考:https://www.cnblogs.com/CarpenterLee/p/5488070.html
  • 导包:import java.util.PriorityQueue;
  • 定义:PriorityQueue<String> q = new PriorityQueue<String>();
  • 常用方法:与一般队列一样
  • 排序重写规则:找了一堆都没找到……大概与C++的sort一样吧,如果返回正数,要把o1替代o2成为堆顶;返回负数,则相反。通过代码猜的不一定对

题目里涉及的知识:

Java 整数和字符串互相转换:

//整数转换为字符串:
String a = " ";  
int b = Integer.parseInt(a);
//字符串转换为整数:
int b = 0;
String a = STring.valueOf(b);

七、二叉树

  • Java翻转ArrayList:Collections.reverse(list);
    没有返回值,原地翻转列表

  • Java排序函数:
    对数组排序:Arrays.sort(arr);
    对列表排序:用列表自带的排序函数
    ArrayList<Integer> list = new ArrayList<>();
    list.sort();

  • Java的int最大值最小值:
    最大值:Integer.MAX_VALUE ,2^31 - 1
    最小值:Integer.MIN_VALUE

  • 数组可以作为Java方法的返回值:int[] func(int a, int b){}
    调用函数时:int[] arr = func(a, b);

  • Math常用数学运算
    乘方:Math.pow(a, b) a的b次方
    开平方:Math.sqrt(double a)

猜你喜欢

转载自blog.csdn.net/yeeanna/article/details/127290182