0算法问题

数组

数组是存放在连续内存空间上的相同类型数据的集合

链表

链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

栈和队列

栈实现队列
队列实现栈

单调栈

优先队列(堆)

  • PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o1.getValue() - o2.getValue());
  • peek()//返回队首元素
    poll()//返回队首元素,队首元素出队列
    add()//添加元素
    size()//返回队列元素个数
    isEmpty()//判断队列是否为空,为空返回true,不空返回false

双端队列(队首是栈顶)

StackArrayDequeLinkedList
push(e)addFirst(e)/offerFirst(e)addFirst(e)/offerFirst(e)
pop()removeFirst()/pollFirst()removeFirst()/pollFirst()
peek()getFirst()/peekFirst()getFirst()/peekFirst()

合并K个升序链表
前 K 个高频元素
丑数
滑动窗口最大值

动态规划

子序列问题

注:子序列默认不连续 子数组默认连续
最长递增子序列
最长连续递增子序列
最长重复子数组
最长公共子序列

01 背包问题

重量价值
物品0115
物品1320
物品2430
物品\容量01234
A015151515
B015152035
C015152035

注: dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

for (int i = 0; i < 8; i++){
      for (int j = n; j >= weight[i]; j--) {
             dp[j] = Math.max(dp[j], dp[j - weight[i]] + val[i]);
      }
}

逆序遍历背包:二维变一维 因为右边需要左边的状态 遍历时不能破坏dp[i-1][jj] 因此只能从大到小遍历

  • 求容量内的最大价值:第一个物品初始化 0,15,15,15
  • 求每个容量的最大价值:0 容量初始化为0 其他全部-00

组合问题:在集合nums中找出和为left的组合 dp[j] += dp[j - nums[i]]

完全背包问题

重量价值
物品0115
物品1320
物品2430
物品\容量01234
A015304560
B015304560
C015304560
  • 01背包完全背包唯一不同就是体现在遍历顺序上,物品无限所以容量从小到大遍历
  • 先遍历物品:0 1 2 此时{0,2} {2,0} 算同一种 因此是求组合的
  • 先遍历容量 :每次都重新遍历物品 {0,2}{2,0}算两种答案
// 先遍历物品,再遍历背包
for(int i = 0; i < weight.size(); i++) { // 遍历物品
    for(int j = weight[i]; j <= bagWeight ; j++) { // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
    }
}

双指针和前缀和

双指针解法

和>=k的长度最小子数组
乘积>k的子数组个数
左右子数组和相等的位置
包含相同01数的子数组个数
三数之和

前缀和解法

因为有负数,不能用双指针。用大前缀减去小前缀
和==k的子数组个数

排序算法(插入、选择、交换+归并)

在这里插入图片描述

直接插入排序(有序表和无序表)
  • 基本思想:把n个元素看为一个有序表和一个无序表 开始时有序表只有一个元素 无序表有n-1个元素 每次从无序表取出一个元素 将其与有序表的袁旭比较 插入到它的合适位置 形成新的有序表
  • 共循环 n-1 次
希尔排序(下标+增量 对数据分组 改变逆序对)
  • 直接插入的问题:当插入较小的数 后移的次数很多 影响效率
  • 基本思想:按下标+增量 对数据分组 使用直接排序 随着增量减少 分组逐渐减少 最终被分成一组
简单选择排序(每次选最小 交换)
  • 基本思想:第一次从arr[i]中选择最小的元素与arr[0]交换 以此类推
  • 共循环 n-1 次
堆排序(调整大小顶堆结构)
  • 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。

  • 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右子结点的值,称为大顶堆, 注意 : 没有要求结点的左子的值和右子的值的大小关系。

  • 每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆

  • 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] // i 对应第几个节点,i从0开始编号

  • 小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] // i 对应第几个节点,i从0开始编号
    一般升序采用大顶堆,降序采用小顶堆

  • 基本思想:

  • 将待排序序列构造成一个堆 根据升序降序选择大小顶堆

  • 交换堆顶和末尾元素 将最大元素沉到数组末端

  • 重新调整堆结构 继续交换元素
    如此反复执行,便能得到一个有序序列了。可以看到在构建堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了.

冒泡排序(调整逆序对)
  • 基本思想:从前向后,依次比较相邻元素的值,若发现逆序则交换·

  • 共循环 n-1 次排序

     	3 ,9,-1,10,20
    

(1) 3 ,-1,9,10,20
(2) -1 ,3,9,10,20
(3) -1 ,3,9, 10,20
(4) -1 ,3,9, 10,20

快速排序(右边找小 左边找大 相遇得到真是下标 递归)
  • 基本思想:冒泡排序的改进 通过一趟排序 将要排序的元素分为两个部分 其中以比分的数据比另一部分的数据都要小 再按照这样的方法分别进行快速排序 使整个数据变成有序序列
归并排序-先分后和

在这里插入图片描述

  • 分:分解数据到单个单位
  • 合:共合并n-1次 两个有序子序列 下标i,j 将较小的那个数放入临时数组 i++或者j++ 不断迭代 最后将临时数组复制得到结果
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值