算法&数据结构
算法和数据结构基础模版整理
Wimb
后端开发
展开
-
【专题|排序】快速排序
原理选择一个关键值作为基准值(一般选择第一个元素为基准值元素),将比基准值大的都放在右边的序列中,将比基准值小的都放在左边的序列中。流程从后往前比较,用基准值和最后一个值进行比较。如果比基准值小,则交换位置;如果比基准值大,则继续比较下一个值,指导找到第1个比基准值小的值才交换位置;在从后往前找到第1个比基准值小的值并交换位置之后,从前往后比较。如果有比基准值大的,则交换位置;如果没有,则继续比较下一个,直到找到第1个比基准值大的值才交换位置;重复执行以上过程,指导从前往后比较的索引大于等于从后原创 2020-08-26 09:08:51 · 271 阅读 · 0 评论 -
动态规划 - 01背包问题(Java实现)
【问题描述】 一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大?【思路】 假设前n个物品,总承重为j,物品的重量为w,其最大价值为v[n,j]。 在背包的总承重不变的前提下,一个物品是否放入背包中...原创 2018-09-25 19:32:43 · 6799 阅读 · 0 评论 -
主定理与递归树计算算法时间复杂度
【主定理】【递归树】每一节点中都将当前的自由项n留在其中,而将两个递归项T(n/2) + T(n/2)分别摊给了他的两个子节点,如此循环。图中所有节点之和为:nlogn可以得到递归树的规则为: (1) 每层的节点为T(n) = aT(n / b) + f(n)中的f(n)在当前的n/b下的值; (2) 每个节点的分支数为a; (3)每层的右侧标出当前层中...原创 2019-01-02 15:55:53 · 764 阅读 · 0 评论 -
算法专题(一)递归
介绍递归的定义、特点和基本原理;在此基础上给出一系列性质,对递归问题进行分类;通过经典问题讲解递归算法的实现定义递归就是程序调用自身的编程技巧;特点1)递归就是在过程或者函数里面调用自身;2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口;3)在递归调用过程中,系统位每层的返回点、局部量开辟栈来存储。递归次数越多,容易造成栈溢出等。经典问题1.汉诺...原创 2019-06-27 10:18:11 · 326 阅读 · 0 评论 -
04.【数组】二维数组的查找
题目描述在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。思路:从矩阵左下角开始遍历,根据其值大小移动位置即可。通过代码public class Solution { public boolean Find(int targe...原创 2019-03-02 00:50:23 · 145 阅读 · 0 评论 -
06.【单链表】反转单向链表
问题单链表的反转分析代码实现public static ListNode reserve(ListNode head){ if(head == null) return null; ListNode pre = null; ListNode next = null; while(head != null){ next = head.next; head.next = pre; pre = head; head = next; } return原创 2020-09-10 15:39:49 · 122 阅读 · 0 评论 -
07.【二叉树】根据前序和中序遍历重建二叉树
问题输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。分析(1)先根据前序遍历的第一个节点root找到分界点i(2)将前序遍历数组和中序遍历数组按照分界点进行划分(3)递归代码实现 public TreeNode buildTree(int[] preorder, int[] inorder) { if(preorder.length == 0) return null; in原创 2020-09-10 15:47:08 · 157 阅读 · 0 评论 -
07.【二叉树】根据前序和中序重建二叉树
题目描述输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。思路首先从前序找出第一个结点作为根节点,从中序遍历中找到该节点,那么中序遍历中其位置前的结点就属于该节点的左子树,相反其位置的右边属于该节点的右...原创 2019-03-04 20:12:40 · 553 阅读 · 0 评论 -
09.【栈+队列】用两个栈实现一个队列
题目描述用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。思路stack1用于出栈,stack2用于入栈,入栈时检查stack1是否有元素,放于stack2中;出栈时检查stack1是否有元素,放于stack2中。代码实现import java.util.Stack;public class Solution { Stack<...原创 2019-03-06 00:07:27 · 101 阅读 · 0 评论 -
10.【递归】跳台阶+变态跳台阶
题目描述一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。思路简单的递归实现即可代码实现public class Solution { public int JumpFloor(int target) { return Jump(target); } public in...原创 2019-03-07 22:01:53 · 96 阅读 · 0 评论 -
12.【回溯】矩阵中的路径
题目描述请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字...原创 2019-05-29 20:39:55 · 119 阅读 · 0 评论 -
12.【深度优先搜索+广度优先搜索】机器人的运动范围
【题目】地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?【分析】(注)可避免重复计算,上下左右方向可以缩减为向下和向右方向运动深度优先搜索p原创 2020-08-27 10:22:14 · 251 阅读 · 0 评论 -
14.【求导+动态规划+贪心】减绳子
题目给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。分析(1)数学推导式解决推论1:如果把整数n分为两部分,那么这两部分的值相差越小乘积越大。举例: x*y = xy; (x-1)*(y+1)=xy-(y-x)-1;原创 2020-08-27 13:20:12 · 210 阅读 · 0 评论 -
16.【快速幂】数字的整数次方
(一)题目1:快速幂实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。分析(数学前提)(a+b) mod p = (a mod p + b mod p) mod p(a*b) mod p = (a mod p * b mod p) mod p举例代码实现public double myPow(double x, int n) { double res = 1.0原创 2020-08-27 15:48:52 · 165 阅读 · 0 评论 -
17.【大数问题】打印1到最大的n位数
题目变体:大数相加思路1.反转两个字符串,便于从低位到高位相加和最高位的进位导致和的位数增加;2.对齐两个字符串,即短字符串的高位用‘0’补齐,便于后面的相加;3.从头遍历,把两个正整数的每一位都相加,并加上进位;4.最高位有进位则补上进位;5.逆序输出;public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s1 = sc.nextLine();原创 2020-08-28 08:44:44 · 117 阅读 · 0 评论 -
18.【单链表】删除链表节点
题目给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。代码实现public ListNode deleteNode(ListNode head, int val) { if(head.val == val) return head.next; ListNode f = head.next; ListNode l = head; while(f!=null){原创 2020-08-28 08:55:45 · 206 阅读 · 0 评论 -
18_2.【链表】删除链表中重复节点
题目删除链表中重复节点代码实现public class DeleteDuplication { /** * 删除链表中的重复节点 * 1、新建一个头节点,以防止第一个节点被删除。 * 2、保存当前节点的前一个节点,循环遍历整个链表,如果当前节点的值与下一个节点的值相等 * 则将当前节点的值与 next.next节点的值比较,直到不相等或者null为止, * 最后将当前节点的前一个节点 pre指向最后比较不相等的节点 * 3、如果当前节点与next节点不相等,则直接原创 2020-08-29 14:40:11 · 194 阅读 · 0 评论 -
21.【数组】调整数组顺序使奇数位于偶数前面
题目描述输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。思路方法1:新建数组分别按照数组中的奇数和偶数进行保存即可。方法2:类似于插入排序,先用一个K保存当前奇数个数,之后将遍历的奇数放入第K+1的位置,之后将数组第K+2的位置到i的位置数整体往后移即可。代码...原创 2019-03-10 01:20:25 · 105 阅读 · 0 评论 -
22.【链表】链表中的倒数第k个节点
题目描述输入一个链表,输出该链表中倒数第k个结点。思路先让一个指针往后移动k个节点,接着头结点和该指针一起移动,当该指针移至尾节点,输出即可。代码实现/*public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val;...原创 2019-03-10 23:43:27 · 105 阅读 · 0 评论 -
24.【链表】单链表反转
题目描述输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。思路方法一:先用栈保存依次保存链表的结点,之后用新的链表保存栈中的结点值即可。方法二:利用一个新的结点不断保存前后两个节点的指向,从头到尾更改节点指向即可。代码实现/*** public class ListNode {* int val;* ListNode ...原创 2019-03-03 14:49:01 · 132 阅读 · 0 评论 -
25.【链表】反转单链表+合并两个排序的链表
题目描述输入一个链表,反转链表后,输出新链表的表头。代码实现/*public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}*/public class Solution { public Lis...原创 2019-03-11 22:09:55 · 296 阅读 · 0 评论 -
26.【二叉树】树的子结构
题目输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构, 即 A中有出现和B相同的结构和节点值。例如:给定的树 A:给定的树 B:返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。分析(1)在树A中找到树B的根节点位置;(2)判断树A和树B之间结构是否相同;代码实现public boolean isSubStructure(TreeNode A, TreeNode B) { if(B == null||A原创 2020-08-30 14:08:02 · 185 阅读 · 0 评论 -
27.【二叉树】二叉树镜像
题目描述操作给定的二叉树,将其变换为源二叉树的镜像。输入描述:二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 7 5...原创 2019-03-13 21:51:19 · 168 阅读 · 0 评论 -
28.【二叉树】对称二叉树
代码实现 public boolean isSymmetric(TreeNode root) { return (root == null)?true:recur(root.left,root.right); } public boolean recur(TreeNode l,TreeNode r){ if(l == null&&r == null) return true; if(l == null||r == null|.原创 2020-08-30 15:51:41 · 155 阅读 · 0 评论 -
29.【数组】顺时针打印矩阵
题目描述输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.思路设置矩阵的行的上限和下限;列的上限和下限;按照一圈的遍历顺序进行,注意一定要控制好打印时的矩阵行和列,上下...原创 2019-03-14 22:10:22 · 142 阅读 · 0 评论 -
30.【栈】包含min函数的栈+栈的压入和弹出
题目定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。分析利用辅助栈实现数据保存代码实现class MinStack { Stack<Integer> A, B; public MinStack() { A = new Stack<>(); B = new Stack<>(); } public vo原创 2020-08-30 16:06:28 · 129 阅读 · 0 评论 -
32.【二叉树】二叉树从上到下打印
题目描述从上往下打印出二叉树的每个节点,同层节点从左至右打印。思路利用一个队列按照层的顺序依次入队列遍历即可。代码实现import java.util.ArrayList;import java.util.Deque;import java.util.LinkedList;/**public class TreeNode { int val = 0; ...原创 2019-03-17 00:04:52 · 125 阅读 · 0 评论 -
33.【二叉树+递归分治】二叉搜索树的后序遍历序列
题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。思路满二叉树:从高到低,除了叶结点外,所有结点的左右结点都存在。完全二叉树:比满二叉树少几个叶结点,从左向右放子结点。平衡二叉树:空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树也都是平衡树。、二叉搜索树:空树或...原创 2019-03-17 21:58:51 · 293 阅读 · 0 评论 -
34.【深搜】二叉树中和为某一值的路径
题目描述输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)思路首先思考节点值的和为输入的整数,每条路径都一定是从根节点到叶子节点,在数据结构中从根节点到叶子节点的遍历称之为深度优先遍历DFS。因此整个过程可以采用先序遍历方式的DFS,即...原创 2019-03-18 21:44:27 · 92 阅读 · 0 评论 -
35.【链表】复杂链表的复制
题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)思路代码实现/*public class RandomListNode { int label; RandomListNode next ...原创 2019-03-20 09:19:49 · 122 阅读 · 0 评论 -
36.【二叉树】二叉搜索树与双向链表
题目描述输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。思路本题是中序遍历的非递归实现的升级题目,按照中序遍历的顺序建立二叉树即可。代码实现/**public class TreeNode { int val = 0; TreeNode left = null; TreeNode ri...原创 2019-03-22 20:33:18 · 121 阅读 · 0 评论 -
37.【二叉树】序列化二叉树
题目描述请实现两个函数,分别用来序列化和反序列化二叉树思路算法思想:根据前序遍历规则完成序列化与反序列化。 所谓序列化指的是遍历二叉树为字符串;所谓反序列化指的是依据字符串重新构造成二叉树。 依据前序遍历序列来序列化二叉树,因为前序遍历序列是从根结点开始的。 当在遍历二叉树时碰到Null指针时,这些Null指针被序列化为一个特殊的字符“#”。...原创 2019-05-05 21:59:24 · 187 阅读 · 0 评论 -
38.【全排列】字符串的排列
题目描述输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。输入描述:输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。思路回溯法,具体见代码注释代码实现package com.wumeng.E;import jav...原创 2019-03-24 10:54:09 · 365 阅读 · 0 评论 -
39.数组中出现次数超过一半的数字
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。思路先遍历一遍,设置一个士兵变量存取当前出现次数多的那个数,第二次遍历判断当前士兵存的数的个数是否超过数组长度一半即可。代码实现public class Sol...原创 2019-03-20 22:08:55 · 98 阅读 · 0 评论 -
40.【快排+分治】最小的K个数
题目描述输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。思路最简单的就是数组排序从小到大排序输出前K个数即可。本题使用Java中的PriorityQueue实现。import java.util.PriorityQueue;import java.util.Comparator;import java....原创 2019-03-24 20:19:05 · 316 阅读 · 0 评论 -
41.数据流中的中位数
题目描述如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。思路用一个ArrayList存每次输入的值,用Collections进行排序,取中位数即可。代...原创 2019-05-07 21:54:30 · 202 阅读 · 0 评论 -
42.【动态规划】连续子数组的最大和
题目描述HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序...原创 2019-03-22 21:34:52 · 96 阅读 · 0 评论 -
47.【动态规划】礼物的最大价值
题目(DP模板题)在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?代码实现 public int maxValue(int[][] grid) { int row = grid.length; int col = grid[0].length; int [][]dp = new in原创 2020-09-10 21:08:52 · 185 阅读 · 0 评论 -
48.【动态规划】最长不含重复字符的子字符串
题目:最长不含重复字符的子字符串请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。假设字符串中只包含从’a’到’z’的字符。例如,在字符串中"arabcacfr",最长非重复子字符串为"acfr",长度为4。分析主要思路:使用动态规划,记录当前字符之前的最长非重复子字符串长度f(i-1),其中i为当前字符的位置。每次遍历当前字符时,分两种情况:1)若当前字符第一次出现,则最长非重复子字符串长度f(i) = f(i-1)+1。2)若当前字符不是第一次出现,则首先计算当前字原创 2020-09-11 09:59:55 · 2056 阅读 · 0 评论 -
49.【指针/数学】丑数
题目描述把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。思路首先从丑数的定义我们知道,一个丑数的因子只有2,3,5,那么丑数p = 2 ^ x * 3 ^ y * 5 ^ z,换句话说一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到,那么我们从1开...原创 2019-03-28 20:11:12 · 344 阅读 · 0 评论