算法与数据结构
IronWring_Fly
这个作者很懒,什么都没留下…
展开
-
换酒问题
换酒问题小区便利店正在促销,用 numExchange 个空酒瓶可以兑换一瓶新酒。你购入了 numBottles 瓶酒。如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。请你计算 最多 能喝到多少瓶酒。import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays;public class Main1 { public sta原创 2020-11-06 15:30:02 · 526 阅读 · 1 评论 -
计算好数对
给你一个整数数组 nums 。如果一组数字 (i,j) 满足 nums[i] == nums[j] 且 i < j ,就可以认为这是一组 好数对 。返回好数对的数目。有两种方法:第一种是暴力法,从数组左边第一位挨个数,看有多少好数对;第二种方法时公式法,利用组合公式,先计算出数组中每个元素出现了多少次,然后利用A=(n(n−1)2)A = \left(\frac{n(n-1)}{2}\right)A=(2n(n−1))即可,其实好数对也就是一个集合中的组合数。代码如下://导入Bu.原创 2020-11-06 11:24:50 · 755 阅读 · 0 评论 -
在行列都排好的矩阵中找指定的数字。
在行列都排好的矩阵中找指定的数字。这道在《剑指offer》中也有一道类似的,因为行列都是排好序的,所以可以从二维数组的右上角或者左下角开始比较。以右上角为例,如果数组值大于指定的数字,那么,这个数字一定大于这一行所有的值;如果数组值小于这个数字,那么这个数字一定小于这一列所有的值。代码如下:import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;public class原创 2020-08-06 16:20:03 · 360 阅读 · 0 评论 -
两个链表生成相加链表
做链表的题目,如果练的少一下子想不清楚的话,最好在纸上画一画,然后对照着用纸笔写代码,这样能加深印象,也不容易出错。本次题目如下:假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。给定两个这种链表,请生成代表两个整数相加值的结果链表。例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。可以采用栈的方式,反向保存链表,然后出栈相加,并生成进位。import java.io.Bu原创 2020-08-02 23:03:05 · 251 阅读 · 0 评论 -
将单向链表按某值划分为左边小、中间相等、右边大的形式
思路就是将链表转换为数组,然后利用快速排序的思想解决,不过一直显示算法超时,需要再优化。import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;class Node{ int val; Node next; public Node(int v...原创 2020-02-26 10:29:14 · 419 阅读 · 0 评论 -
判断一个链表是不是回文结构
方法一:将整个链表入栈import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;import java.util.Stack;class Node{ public int val; public Node next; public Node(...原创 2020-01-20 15:51:47 · 222 阅读 · 0 评论 -
反转部分单向链表
这道题需要注意换头节点的问题,然后就是先定位需要反转的链表的左右边界位置,然后在这个边界中进行链表的反转操作。import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;class Node{ public int val; public Node ...原创 2020-01-17 10:56:31 · 221 阅读 · 0 评论 -
翻转单向链表和双向链表
这种基础题目,细节问题上很容易出现问题,需要精神高度集中,做到一遍代码敲出来直接运行没有任何问题。import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;class Node { public int val; public Node next;...原创 2020-01-15 13:09:46 · 179 阅读 · 0 评论 -
打印两个升序链表的公共部分
给定两个升序链表,打印两个升序链表的公共部分。常规题目,感觉也没什么好说的。import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;class Node { public int val; public Node next; publi...原创 2020-01-08 16:17:34 · 430 阅读 · 0 评论 -
可见山峰对(高级)
我反而觉得高级篇会简单一些,毕竟不用算全排列并且将其按字典顺序输出,计算过程虽然比较多,但是整个逻辑还是很清楚的。这里依然用到了单调栈这种数据结构,然后就是入栈和出栈的时候需要计算一下能看到的山峰的个数(需要分类讨论)。 两个辅助函数,一个用来模拟环形结构,一个用来计算组合数。 详细内容还是推荐看书《程序员代码面试指南》,写的非常详细,一看就懂了。import java.util.S...原创 2020-01-07 16:29:28 · 309 阅读 · 0 评论 -
可见的山峰对数量 (初级)
一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度。比如,{3,1,2,4,5},{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山。3->1->2->4->5->3 方向叫作 next 方向(逆时针),3->5->4->2->1->3 方向叫作 last 方向(顺时针)。山峰 A 和 山峰 B 能够相...原创 2020-01-07 11:40:54 · 627 阅读 · 0 评论 -
最大值减去最小值小于或等于num的子数组数量
这道题的两个队列都是严格单调队列,可以结合之前的单调栈结构和生成窗口最大值数组两道题结合起来理解。不过,为什么 1, 2, 1 num = 1 时,结果是 6 呢?import java.util.LinkedList;import java.io.IOException;import java.io.BufferedReader;import java.io.InputStream...原创 2020-01-06 17:06:58 · 551 阅读 · 1 评论 -
求最大子矩阵的大小
这道题需要结合单调栈结构来解决。先用height数组统计出map的连续的1的个数,这里需要按行来进行计算。然后将height数组放入单调栈中,结合严格单调栈结构的题,计算出左右最近且比它小的数的位置,然后长宽相乘即可。import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamRea...原创 2020-01-05 11:48:43 · 195 阅读 · 0 评论 -
单调栈结构
给定一个不含有重复值的数组 arr,找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i] 小的位置。返回所有位置相应的信息。 利用严格单调的栈,这里指,栈中存储的下标,对应的数组中的值,是严格单调的。 如果新加入的值比栈顶元素对应的值大,则弹出栈顶。(这里都指数组下标对应的数组元素值的大小。) 要处理的是弹出栈的那个值,它下边的值一定比他小(左值);又因为弹出了,所以...原创 2019-12-27 15:32:14 · 191 阅读 · 0 评论 -
生成窗口最大值数组
有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置,求每一种窗口状态下的最大值。(如果数组长度为n,窗口大小为w,则一共产生n-w+1个窗口的最大值)代码如下:import java.util.LinkedList;import java.io.BufferedReader;import java.io.IOException;import j...原创 2019-12-26 20:18:26 · 162 阅读 · 0 评论 -
用栈来解决汉诺塔问题
这是一道比较比较复杂的问题,完全写下来会非常浪费时间,具体分析过程参见《程序员代码面试指南》。后面如果我有时间,就补充一下。思路一:递归import java.util.Scanner;public class Main{ public static int hanoiProblem(int num){ if (num < 1) { re...原创 2019-12-23 16:24:05 · 438 阅读 · 0 评论 -
用一个栈去排序另一个栈
一个栈中元素的类型为整型,现在想将该栈从顶到底按从大到小的顺序排序,只许申请一个栈。除此之外,可以申请新的变量,但不能申请额外的数据结构。如何完成排序? 这道题的思路和插入排序非常像,两个栈,一个stack,一个help,辅助变量cur,将stack中的栈顶元素弹出,并与help的栈顶元素进行比较。如果比栈顶元素小,就直接压入,如果比栈顶元素大,那就将help的栈顶移到stack中,直到c...原创 2019-12-22 10:28:36 · 235 阅读 · 0 评论 -
猫狗队列
实现一种猫狗队列的结构,要求如下:用户可以调用 add 方法将 cat 或者 dog 放入队列中用户可以调用 pollAll 方法将队列中的 cat 和 dog 按照进队列的先后顺序依次弹出用户可以调用 pollDog 方法将队列中的 dog 按照进队列的先后顺序依次弹出用户可以调用 pollCat 方法将队列中的 cat 按照进队列的先后顺序依次弹出用户可以调用 isEmpty 方...原创 2019-12-21 17:45:16 · 147 阅读 · 0 评论 -
仅用递归和栈操作逆序一个栈
思路就是:每次从利用递归,从栈中取出栈底元素,然后将其他元素按原来的顺序压入栈中即可。import java.util.Stack;import java.util.Scanner;public class Main { public static int getAndRemoveLastElement(Stack<Integer> stack) { ...原创 2019-12-20 19:11:44 · 136 阅读 · 0 评论 -
两个栈组成队列
用两个栈实现队列,支持队列的基本操作。包括 add(),poll(),peek() 常规题目,也没什么特别好说的地方,不过这里我发现用 switch 匹配 String 会比多个 if 条件利用 equals 判断来的快一些。然后,得注意拼写,这里我之前把 poll 拼写成了 pool,浪费了很多时间。代码如下:import java.util.Stack;import java....原创 2019-12-16 11:25:15 · 101 阅读 · 0 评论 -
设计getMin功能的栈(方案二)
实现一个特殊功能的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。这次的方案是,stackMin的栈中,每次判断最小的数,并将最小的数压入栈中。然后这次使用了switch,jkd 7 之后,switch支持String了,所以代码看上去会更简洁一些。代码如下:import java.util.Stack;import java.util.Scanner;public...原创 2019-12-16 10:17:05 · 97 阅读 · 0 评论 -
二维数组中查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 如果目标值比9大,那肯定比第一行所有的数都大,目标值不可能出现在第一行;如果比9小,则肯定比最后一列所有的值都小,目标值不可能出现在最后一列。根据这个规律可以写出如下的代码:import org...原创 2019-12-16 10:12:49 · 86 阅读 · 0 评论 -
设计一个有getMin功能的栈,包含Sanner函数的写法
实现一个特殊的栈,在实现栈的基本功的基础上,再实现返回栈中最小元素的操作 这道题本身很简单,比较复杂的地方是,在牛客网上利用scanner函数输入数据的时候,有很多的坑。题目本身倒是真没花费我多少时间。希望我的这份代码能帮到你。代码如下:import java.util.Scanner;import java.util.Stack;public class Main { ...原创 2019-12-15 10:58:25 · 127 阅读 · 0 评论 -
股票的最大值
把某股票的价格按照先后顺序存储在数组里,请问买卖该股票一次可能获得的最大利润是多少?例如,一只股票在某些事件结点的价格为{9, 11, 8, 5, 7, 12, 16, 14}。如果我们能在价格为5的时候买入并在价格为16时卖出,则能收获最大的利润11. 简单思路就是类似冒泡排序的方法,暴力遍历数组,找到所有的可能值,然后找最小。 进阶思路就是,保存数组中第 i 个数组前面所有数字中最...原创 2019-12-14 10:18:54 · 410 阅读 · 0 评论 -
圆圈中最后剩下的数组
0, 1, n - 1 这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除m个数字。求出这个圆圈里剩下的最后一个数字。 这道题可以利用LinkedList模拟这个圆圈,然后利用余数哈希法产生循环坐标,这里就和一致性哈希那里的思想是一样的。代码如下:import org.junit.Test;import java.util.LinkedList;import java.ut...原创 2019-12-13 10:58:32 · 214 阅读 · 0 评论 -
最长回文子串
给出一个包含大小写字母的字符串。求出由这些字母构成的最长的回文串的长度是多少。数据是大小写敏感的,也就是说,“Aa” 并不会被认为是一个回文串。这道题其实也很简单,就是利用一个简单的HashSet,遍历字符串,统计重复字符个数就行了。如果是奇数,那就是重复的字符数 * 2 + 1,否则就是重复的字符数 * 2。代码如下:import org.junit.Test;import ja...原创 2019-12-12 10:19:16 · 121 阅读 · 0 评论 -
扑克牌顺子
从扑克牌中随机抽取5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字,A为1,J为11,Q为12,K为13,而大小网可以看成是任意数字。 上次做了骰子点数的题,这次突然来了这么简单的一道题,怎么说呢,感觉似乎有点不太适应。 这道题可以把大小王看作是数字0,这样的话,其实题目的模型已经建立好了,就是在[0 ~ 13]这个区间范围内随机的选取5个值,然后判断这5个值是不是连...原创 2019-12-12 09:40:50 · 426 阅读 · 0 评论 -
n个骰子的点数,循环法Java
利用循环的方法求解这道题目的话是有一些绕的,我画了下面这个示意图,可以帮助你辅助理解。 依然是利用数组下标表示n个骰子点数之和的可能取值,不过这里我们不对下标做特殊处理,只是将暂时没有出现的骰子点数之和用0表示。 数组元素依然是该骰子点数和可能出现的次数。图上我画了三个数组,但实际上我们也可以循环使用两个数组,来达到这个效果。代码如下:import org.junit.Test;...原创 2019-12-11 10:00:45 · 238 阅读 · 0 评论 -
n个骰子的点数
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。 这是我第一次接触high level的题目,明显能感觉到,和普通题目以及中等难度的题目之间的差距。 直接就去考虑n个骰子难度有点大,我们可以先考虑1个骰子的情况。 如果现在只有一个骰子,那么是什么情况呢。那朝上一面点数只和就只有6种情况,分别是{1, 2, 3, 4, 5, 6},则点数...原创 2019-12-09 10:23:30 · 297 阅读 · 0 评论 -
滑动窗口的最大值
给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。 例如,如果输入数组{2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小3,那么一共存在6个滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6, 5}。 这道题可以利用双端队列来实现滑动窗口的效果,我们直接在双端队列中存储滑动窗口的最大值,然后随着窗口的移动,将之前存在队列中的数值再删去就可以了。代码如下:...原创 2019-12-06 10:30:30 · 123 阅读 · 0 评论 -
左旋转字符串
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它! 这道题目和上一篇翻转字符串的思路是差不多的,不过需要注意的是,这道题目的异常情况比较多,函数涉及到两...原创 2019-12-05 11:14:52 · 136 阅读 · 0 评论 -
翻转字符串
翻转单词顺序输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和字母做同样的处理。例如,输入字符串 “I am a student.”, 则输出"student. a an I" 这道题目如果用Java的字符串api做非常的简单,都是一些基本操作。public void reverseString(String str) { if (str == n...原创 2019-12-05 10:11:06 · 139 阅读 · 0 评论 -
和为s的连续正数序列
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!输出描述:输出所有和为S的连续正数序列。序列内按...原创 2019-12-04 10:02:54 · 138 阅读 · 0 评论 -
数组中只出现一次的数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 这道题比较有意思的地方在于,你可以想象自己现在是在玩开心消消乐,把数组中出现了两次的数字想办法消掉,那么剩下的元素就是只出现了一次的。 那,消掉相同的数字,很明显就需要利用异或,如果数组中只有一个数字出现了一次,其他都出现了两次,那么直接将数组中所有的数字都依次异或,最终剩下的就是在数字中只出...原创 2019-12-03 10:04:16 · 137 阅读 · 0 评论 -
二叉树的深度
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 这道题目除了顺序遍历树的所有路径,保存路径长度最大的值之外,还可以利用动态规划的思想。 如果一个结点只有左子节点,没有右子结点,那么以这个结点作为根结点的树,它的深度就是左子结点的深度+1;同理,如果一个结点只有右子节点,没有左子结点,那么以这个结点作为根结点的树,...原创 2019-12-02 08:58:36 · 238 阅读 · 0 评论 -
二叉搜索树的第k大节点
给定一颗二叉搜索树,找出第k大结点 这道题也没什么好说的,就是二叉搜索树的中序遍历,找到第k大的数返回就可以了。不过需要注意的是,《剑指offer》这本书上使用C写的,所以迭代的时候,就直接使用的是k的引用,而Java中没有这种语法,所以这里我用了一个全局变量,稍微修改了一下,总之效果是一样的。import org.junit.Test;class TreeNode{ int ...原创 2019-12-01 09:58:29 · 170 阅读 · 0 评论 -
数字在排序数组中的位置
统计一个数字在排序数组中出现的次数。 在排序数组中查找一个数,这明显就需要利用二分法。不过现在需要在数组中找某个数出现的次数,那么我们就需要找到这个数字在数组中第一次出现的位置,以及最后一次出现的位置,将这两个下标一减再加上1就是我们需要的结果。找第一次出现的位置时,我们利用二分法找到了目标值,它的下标为i,此时还不能停止寻找,我们得判断一下 i - 1 位置上的数是否也是目标值,如果是...原创 2019-11-30 11:03:53 · 770 阅读 · 0 评论 -
两个链表的第一个公共结点
输入两个链表,找出它们的第一个公共结点。public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }} 首先分析题目,从题目给出的链表结构可以看出这其实是一个单向链表,那么单向链表,还要有公共的子节点,那这两个链...原创 2019-11-29 09:45:13 · 138 阅读 · 0 评论 -
数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。思路一:暴力法 暴力法,就是遍历数组中的每一个元素,并且和这个元素之后的每一个元素进行比较,这样来统计逆序对的个数。时间复杂度O(n2)。思路二:区间比较法(基于归并排序) 我们转换思路,不一上来就直接在整个数组区间上进行比较,而是采用简化问题的方法,拆分区间...原创 2019-11-28 16:43:41 · 305 阅读 · 0 评论 -
第一个只出现一次的字符
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). 这道题让我深深的体会了一下HashMap的函数以及与LinkedHashMap的区别。 先说解题思路:题目要求很明确,就是遍历字符串,并且给字符计数,计数之后,找到计数为1的字符即可。很明显这需要用到hashmap,key就...原创 2019-11-27 10:54:22 · 133 阅读 · 0 评论