算法题——LeetCode/剑指Offer
纪录刷题
生于四海
一个在科研路上越走越远的猴子
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
(JAVA)剑指offer 15 二进制中1的个数
题目描述 位运算: 因为除法的效率比移位运算要低得多,在实际编程中应尽可能地用移位运算符代替乘除法。 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如,把9表示成二进制是1001,有2位是1,即应输出2. 解法: 把一个整数减去1后再和原来的数做&运算,得到的结果相当于把整数的二进制中最右边的1变成0. private static int intNumberOf1(int n){ // 注意防止负数右移出现死循环 int原创 2021-01-04 15:26:02 · 267 阅读 · 0 评论 -
剑指offer——单例设计模式
单例模式特点: 单例类只能有一个实例 单例类必须自己创建自己的唯一实例 单例类必须给所有其他对象提供这一实例 饿汉式 饿汉式单例模式:饿汉就是类一旦加载,就把单例初始化完成,保证getInstance时,单例已经存在 饿汉式在类创建的同时就已经创建好了一个静态的对象供系统使用,天生就是线程安全的 class SingletonH{ private SingletonH(){} private static final SingletonH single = new Singleton原创 2020-12-02 12:47:01 · 199 阅读 · 1 评论 -
(JAVA)剑指Offer 14 剪绳子——动态规划/贪婪算法介绍
动态规划 常用场景: 求一个问题的最优解(通常是最大值或最小值),而且该问题能够分解成若干个子问题,并且子问题之间还有重叠的更小子问题,就可以考虑使用动态规划来解决。 特点1:求解(子)问题的最优解 特点2:整体问题的最优解是依赖各个子问题的最优解 特点3:将大问题分解成若干个小问题,这些小问题之间还有相互重叠更小的子问题 特点4:从上往下分析问题,从下往上求解问题 一般来说从解决最小问题开始,并把已经解决的子问题的最优解存储下来(置于一维或二维数组中),并把子问题的最优解组合起来逐步解决整体问题。原创 2021-01-02 17:06:17 · 310 阅读 · 0 评论 -
(JAVA)LeetCode 20 有效的括号
题目描述 给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 注意空字符串可被认为是有效字符串。 思路:对于括号的匹配问题,数据结构中已经详细介绍,那就是借助栈的思想-后进先出 碰到 ‘(’, ‘{’, ‘[’,入栈 碰到相反的括号那么出栈进行比较 代码: class Solution { public boolean isValid(Str原创 2020-11-21 13:26:46 · 132 阅读 · 0 评论 -
(JAVA)LeetCode 234 回文链表
题目描述 请判断一个链表是否为回文链表。 解法一: 思路:遍历链表获得链表的长度,采用栈后进先出的思想,将链表的前半部分入栈,每个元素出栈判断是否与链表的元素(长度为奇数时需要向后遍历一个)相等。 查看LeetCode题解:也可以使用双指针法,先将链表元素置于数组中,使用双指针逐个判断是否为回文,时间复杂度和空间复杂度如该解法相同。 class Solution { public boolean isPalindrome(ListNode head) { if(head==原创 2020-11-20 14:56:15 · 119 阅读 · 0 评论 -
(JAVA)LeetCode 198 打家劫舍
题目描述 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 LeetCode解释: 如果房屋数量大于两间,应该如何计算能够偷窃到的最高总金额呢?对于第 k(k>2) 间房屋,有两个选项: 偷窃第 k 间房屋,那么就不能偷窃第 k−1 间房原创 2020-11-19 20:22:44 · 140 阅读 · 0 评论 -
(JAVA)LeetCode 1 两数之和
class Solution { public int[] twoSum(int[] nums, int target) { // int [] solution = new int [2]; // HashMap<Integer,Integer> hashMap = new HashMap<>(); // for(int i=0;i<nums.length;i++){ // if(hashMap.原创 2020-11-18 13:55:26 · 115 阅读 · 0 评论 -
(JAVA)LeetCode 141 环形链表
题目描述 给定一个链表,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。 如果链表中存在环,则返回 true 。 否则,返回 false 。 解法一:哈希表 思路:借助哈希表是很常用的方法,尤其是在判断是否重复访问一个数据的时候原创 2020-11-17 11:09:09 · 106 阅读 · 0 评论 -
(JAVA)LeetCode 70 爬楼梯
题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数 分析: 要求 n 层的台阶的走法,由于一次走 1 或 2 个台阶,所以上到第 n 个台阶之前,一定是停留在第 n - 1 个台阶上,或者 n - 2 个台阶上。 如果用 f ( n ) 代表 n 个台阶的走法。 那么 f(n)=f(n-1)+f(n-2),f(1)=1,f(2)=2。 发现这就是斐波那契数列(Fibonacci s原创 2020-11-16 15:28:03 · 113 阅读 · 0 评论 -
(JAVA)LeetCode 534 二叉树的直径
题目描述 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。 注意:两结点之间的路径长度是以它们之间边的数目表示。 解法:深度优先遍历 两结点之间的路径长度(思考后一定是叶子结点之间存在最大路径) 两个叶子节点之间的最短路径 = 根节点的左右儿子的深度之和 最大值(Math.max)判断,声明变量判断 即问题就转换为在求二叉树深度中加入对最大最短 class Solution { int max=0;原创 2020-11-15 15:38:19 · 158 阅读 · 0 评论 -
(JAVA)LeetCode 53 最大子序和
题目描述 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 解法一:暴力解(对于长序列时间超出) 两次循环,使用 i 和 j 分别做子序列的左界和右界,对每个子序列内的数据求和,比较得到最大子序列的和。 public int maxSubArray(int[] nums) { int max=Integer.MIN_VALUE; for(int i=0;i<nums.length;i++){原创 2020-11-13 18:13:13 · 152 阅读 · 0 评论 -
(JAVA)LeetCode 101 对称二叉树
题目描述 给定一个二叉树,检查它是否是镜像对称的。 解法一:暴力解 审题之后思考,想了一下先中后序遍历的序列,发现中序遍历的序列是一个对称的序列,那么问题就可以转化为先遍历出序列在进行对称字符串的判断…自己能想到的最差的方法 时间复杂度为:遍历二叉树O(n),判断对称字符串O(n),故O(n) 空间复杂度为:需要数组空间存储序列O(n) 问题: 提交后发现代码健壮性存在问题 192 / 195 个通过测试用例 对于[1,2,2,2,null,2] 输入,确实存在着问题,由于存在着数据相同的情况,不能原创 2020-11-12 18:57:35 · 170 阅读 · 0 评论 -
(JAVA)LeetCode 121 买卖股票的最佳时机
题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。 注意:你不能在买入股票前卖出股票。 解法一:暴力解法 两次for循环,每次循环为当前元素与其后面元素中大于当前元素的差值,即利润,设置temp记录最大利润 时间复杂度为O(n)、空间复杂度为O(1) 比较容易想,当然执行用时也是惨不忍睹… public int maxProfit(int[] prices) {原创 2020-11-09 16:58:53 · 126 阅读 · 0 评论 -
(JAVA)LeetCode 160 相交链表
题目描述 编写一个程序,找到两个单链表相交的起始节点。 注意: 如果两个链表没有交点,返回 null. 在返回结果后,两个链表仍须保持原有的结构。 可假定整个链表结构中没有循环。 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。 解题思路: 数据结构链表章节经典的题目(对于链表的操作) (注意:节点相同而非节点值相同) 解法一: - 暴力解法:对链表A中的每一个结点遍历整个链表B并检查链表B中是否存在结点相同 public ListNode getIntersection原创 2020-11-05 14:29:05 · 265 阅读 · 0 评论 -
(JAVA)LeetCode 448 找到所有数组中消失的数字
题目描述 给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。 找到所有在 [1, n] 范围之间没有出现在数组中的数字。 您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。 解法: 解题重点: 仔细审题,数组数据为[1,n] 之间的整数,可以根据该整数作为索引,第一次遍历,将对应索引的数据内的值取负,第二次遍历数据大于0的下标+1即为缺失数据。 public Lis原创 2020-11-03 18:19:07 · 222 阅读 · 0 评论 -
(JAVA)LeetCode 283 移动零
题目描述 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 解法一 - 思路: 采用双指针的思路,首先对当前数组遍历一次,记录非零值,在进行遍历补0(两次遍历) public void moveZeroes(int[] nums) { int j=0; //第一次遍历:将所有非零值移到数组前部分 for(int i=0;i<nums.length;i++){ if(num原创 2020-11-02 20:00:28 · 143 阅读 · 0 评论 -
(JAVA)LeetCode 21 合并两个有序链表
题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 迭代法 注意:设定一个哨兵节点l,可以让我们在最后比较容易地返回合并后的链表 class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode l = new ListNode(-1); ListNode l3 = l; if(l1原创 2020-11-01 20:24:32 · 122 阅读 · 0 评论 -
(JAVA)LeetCode 169 多数元素
题目描述 给定一个大小为 n 的数组,找到其中的多数元素。 多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 解法一:排序 最简单,由题目描述可知,多数元素为出现次数大于n/2,那么排序后数组中间的数一定为多数元素 如果使用语言自带的排序算法,需要使用 O(logn) 的栈空间。如果自己编写堆排序,则只需要使用 O(1) 的额外空间。 时间复杂度为排序时间复杂度,性能较差,对比排序算法的时间复杂度至少为O(nlogn) public原创 2020-10-30 17:21:46 · 111 阅读 · 0 评论 -
(JAVA) LeetCode 136 只出现一次的数字
题目描述 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 解题思路: 由于之前写过对于在一个数组中有两个只出现一次的数,其他均为出现两次的数,所以这次很容易就想到使用位运算符^异或来进行编写 异或思路 任何数和0进行异或等于其本身 一个数与自己异等于0(通过该条很容易想到通过异或消除一个数组中出现两次的数) 代码如下: public int singleNumber(int[] nums) { int resu原创 2020-10-29 12:49:31 · 95 阅读 · 0 评论 -
(JAVA)LeetCode 206 反转链表
题目描述 反转一个单链表。 注意:对于单链表来说,修改链表主要参考数据结构中的链式结构,前插后插法进行节点的处理。 迭代: 上图为LeetCode后图解: 参考数据结构的前插后插法思想,仅需借助两个指针去进行迭代反转。 public ListNode reverseList(ListNode head) { ListNode cur = null; ListNode pre = head; while(pre != null){ // 该步与原创 2020-10-28 20:36:59 · 185 阅读 · 0 评论 -
(JAVA) LeetCode 104 二叉树的最大深度
题目描述: 给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 解法一: 深度优先(递归) 该法比较简单,从下层往上层递归来看: 每一个节点的深度=max(左子树的最大深度,右子树的最大深度)+1 public int maxDepth(TreeNode root) { if(root==null){ return 0; }else {原创 2020-10-27 20:10:01 · 182 阅读 · 0 评论 -
(JAVA)LeetCode 226 翻转二叉树
题目描述: 翻转一棵二叉树。 从题目描述来看,适合用递归,把每个节点的左右子树进行交换。 递归 法一: 从下往上进行交换,即在最后一层开始交换 public TreeNode invertTree(TreeNode root) { if(root == null) return null; root.left = invertTree(root.left); root.right = invertTree(root.right);原创 2020-10-26 19:47:19 · 164 阅读 · 0 评论 -
(JAVA)LeetCode 461 汉明距离
题目描述: 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。 给出两个整数 x 和 y,计算它们之间的汉明距离。 注意: 0 ≤ x, y < 231. 示例: 一:使用Java内置函数直接计算 //异或操作后使用bitCount直接计算 public static int HanMingDistance(int x,int y){ return Integer.bitCount(x^y); } 时间复杂度:O(1) 空间复杂度:O(1) 二:移位 t原创 2020-10-25 16:21:56 · 131 阅读 · 0 评论 -
(JAVA)LeetCode 617 合并二叉树
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。 注意: 合并必须从两个树的根节点开始。 一:深度优先搜索(递归) 依据为二叉树的先序递归实现: 从根节点开始同时遍历两个二叉树,并将对应的节点进行合并。 合并时:判断两个节点都为空,则返回null;如果两个节点均不为空,则返回value值相加后的节点;如果仅一个为原创 2020-10-25 12:49:58 · 145 阅读 · 0 评论
分享