![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法训练
敲代码的洋葱头
v:Yww02240101
展开
-
算法训练 || 169、多数元素
169、多数元素方法一:排序+遍历class Solution { public int majorityElement(int[] nums) { if(nums.length == 1) return nums[0]; //将数组排序是为了统计 Arrays.sort(nums); //统计变量 int count = 1, maxcount = 0; int index = 0, num =原创 2021-09-14 22:39:12 · 117 阅读 · 0 评论 -
算法训练||剑指 Offer 10- I. 斐波那契数列
方法一:普通递归class Solution { public int fib(int n) { if(n == 0){ return 0; }else if(n == 1){ return 1; } return (fib(n-1)+fib(n-2))%1000000007; }}由于递归的深度太深,这种方式是超时的。方法二:记忆递归由于计算过程中,有很多的值是重复.原创 2021-05-29 19:22:14 · 146 阅读 · 0 评论 -
算法训练||剑指 Offer 07. 重建二叉树
方法一:递归,从根结点出发,将根结点下的每一个结点都看作是根结点(递归的思想),然后根据前序遍历的特性,遍历结果的第一个值就是根结点的值,因此可以确定递归的赋值过程,接下来就是确认书的前序遍历和中序遍历的位置,分别对(左子树的前序遍历,左子树的中序遍历),(右子树的前序遍历,右子树的中序遍历)进行递归构建二叉树。这里还有一点特别重要,就是要通过前序遍历中的根结点的值找到中序遍历中根结点的值所在的索引,以便用来划分中序遍历中的左子树和右子树。/** * Definition for a binary t.原创 2021-05-29 16:26:00 · 183 阅读 · 3 评论 -
算法训练||剑指 Offer 06. 从尾到头打印链表
方法一:题目的意思很明显:后进先出,于是可以联想到使用栈的方式/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */class Solution { public int[] reversePrint(ListNode head) { .原创 2021-05-28 00:13:33 · 115 阅读 · 0 评论 -
算法训练||剑指 Offer 04. 二维数组中的查找
方法一:通过每一次比较当前所剩区域的右上角和目标值的大小来进行判断如果右上角的元素等于target,返回true如果右上角的元素小于target,删除右上角元素所在的行 row++如果右上角的元素大于target,删除右上角元素所在的列 col–class Solution { public boolean findNumberIn2DArray(int[][] matrix, int target) { if(matrix.length == 0||matrix[0].原创 2021-05-26 08:04:03 · 114 阅读 · 0 评论 -
算法训练|剑指 Offer 03. 数组中重复的数字
方法一:先把输入的数组排序,排序完后遍历数组,当元素重复时,将元素输出即可。class Solution { public int findRepeatNumber(int[] nums) { Arrays.sort(nums); for(int i = 0;i<nums.length-1;i++){ if(nums[i] == nums[i+1]){ return nums[i]; .原创 2021-05-25 19:40:08 · 174 阅读 · 0 评论 -
算法训练|丑数(最小堆)
class Solution { //最小堆解法 //最小堆的定义:根节点的值比左右结点的值要小(父节点的值比左右孩子结点的值要小) public int nthUglyNumber(int n) { //质因数 int[] factors = {2,3,5}; //定义丑数 int ugly = 0; //用一个set来取出重复的结果集 //将最小堆的根节点存入set中(包括去重),这.原创 2021-04-12 01:22:20 · 144 阅读 · 0 评论 -
算法训练|三数之和(双指针)
思路:对数组进行一次循环,定义两个左右指针,将指针和循环变量i对应的三个数求和,如果为0,则将三个数作为元组加入res中,如果sum大于0,或者sum小于0,都要压缩双指针,让双指针和变量i所对应位置的元素值和趋向于0,同时要对i和left和right都做去重处理。class Solution { public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>>.原创 2021-04-08 18:40:25 · 128 阅读 · 0 评论 -
算法训练|两个数组的交集
思路一:暴力法class Solution { //暴力法,两个for循环遍历数组 public int[] intersection(int[] nums1, int[] nums2) { //使用Set去重 Set<Integer> res = new HashSet<Integer>(); for(int i = 0; i<nums1.length;i++){ for(int j .原创 2021-04-01 14:15:20 · 125 阅读 · 0 评论 -
算法训练|笨阶乘
思路一:使用栈来模拟,分别给每一位分配一个index下标来标记,开始的时候,先将下标为0的元素入栈,因为我们要使用取余数的方式来判断运算符号,而第一位永远是正数,因此先将第一位入栈,然后开始用for循环遍历做取余运算,当index%40的时候是乘号,index%41的时候是除号,index%42的时候是加号,index%43的是减号,减号用负数来表示class Solution { public int clumsy(int N) { Deque<Integer> .原创 2021-04-01 13:13:51 · 86 阅读 · 0 评论 -
算法训练|有效地字母异位词
思路一(哈希表):使用一个数组来记录字符串中每个字符地使用次数,在第一个字符串中每访问一次字符,就将数组中对应字母地访问次数+1,在第二个字符串中每访问一次字符,就将数组中对应字母访问次数-1,最后判断数组是不是全为0,如果是的话就是字母异位词。class Solution { public boolean isAnagram(String s, String t) { //初始化数组所有元素为0 int[] record = new int[26]; .原创 2021-04-01 08:48:36 · 115 阅读 · 0 评论 -
算法训练|子集II
思路一:回溯、去重class Solution { //设置临时集合 List<Integer> temp = new ArrayList<Integer>(); //设置子集总集合 List<List<Integer>> ans = new ArrayList<List<Integer>>(); public List<List<Integer>> subsetsW..原创 2021-04-01 01:38:13 · 153 阅读 · 0 评论 -
算法训练|环形链表
思路:使用哈希表来标记链表中的元素,如果被访问过,直接返回true,如果没有被访问过,则加入哈希表中,哈希表的特性就是同一个元素只能存入哈希表中最多一次,因此可以用来标记访问唯一性。public class Solution { public boolean hasCycle(ListNode head) { //使用哈希表来判断一个元素是否被访问过 HashSet<ListNode> hasSeen = new HashSet<ListNo...原创 2021-03-30 20:34:23 · 95 阅读 · 0 评论 -
算法训练|链表反转
方法一:递归/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */class Solution { public ListNode reverseList(ListNode head) { //初始化curr和prev双指针,与双指针.原创 2021-03-30 19:58:28 · 89 阅读 · 0 评论 -
二分查找,关键在细节!
二分法思路其实很简单,但是细节是其真正的难点,二分法最常见的场景有3种:寻找一个数、寻找左侧边界、寻找右侧边界。这里总结一下二分法的一些细节问题,比如什么时候while(…)里面使用=,什么时候left = mid,什么时候left = mid+1…下面这个是一个二分法的模板:int binarySearch(int[] nums, int target) { int left = 0, right = ...; while(...) { int mid = (rig原创 2021-03-30 13:35:30 · 162 阅读 · 0 评论 -
算法训练|移除链表元素
解题思路:设置哨兵,用来表示头哨兵,目的是让链表不至于没有头结点,同时还要设置prev指针和curr指针,用来操作链表的删除。/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(i..原创 2021-03-30 02:02:32 · 78 阅读 · 0 评论 -
算法训练|移出元素
思路:使用双指针,首先让两个指针同步移动,当val!=nums[fastindex]的时候,slowindex和fastindex是同步移动,这样在后面的时候就可以达到模拟“删除元素”的效果,因为当val==nums[fastindex]的时候,fastindex是移动的,而slowindex是不移动的,两者之间元素就会在val!=nums[fastindex]的时候通过同步移动来“删除”。class Solution { public int removeElement(int[] num...原创 2021-03-30 01:25:32 · 154 阅读 · 0 评论 -
算法训练|螺旋矩阵II
这个题目是一道模拟数组的题目,本身没有什么高深的算法,主要是考察用代码描述抽象事物的能力,根据数组的边界可以确定上、左、下、右的边界,每一次的for循环填充一条边。class Solution { public int[][] generateMatrix(int n) { int[][] array = new int[n][n]; int up = 0,down = n-1,left = 0,right = n-1,index = 1; wh..原创 2021-03-30 01:14:16 · 111 阅读 · 0 评论 -
算法训练|滑动窗口
模式一:滑动窗口模式说明:输入一个数组或者字符串。求解的结果是具有某种特质的子数组或者子字符串。这种情况下,可以使用滑动窗口的方法求解。其中,滑动窗口是一个大小不固定的一个数组,最重要的就是判断这个数组的起始指针和结束指针如何移动。从上面这道题来看的话,如果满足条件,干掉左指针,即左指针向右移动一位,不满足条件的话,右指针向右移动一位....原创 2021-03-29 23:56:59 · 263 阅读 · 0 评论 -
算法训练|买卖股票的最佳时机 II (贪心、动态规划)
贪心思路:题目没有说明交易次数、因此采用每天都交易的方式不断交易,用第二天的股票价格-前一天的股票价格,如果得到的值大于0,则添加进收益和。一直增加,直到收益达到最大。class Solution { public int maxProfit(int[] prices) { int profit = 0; int length = prices.length; for (int i = 1; i < length; i++) { ..原创 2021-01-07 01:00:03 · 196 阅读 · 0 评论 -
算法训练|二分查找(减治法)
二分查找的模板:class Solution { public int search(int[] nums, int target) { int length = nums.length; if(length == 0){ return -1; } int left = 0; int right = length-1; while(left<=right){原创 2020-12-25 17:55:47 · 460 阅读 · 0 评论 -
算法训练|分配饼干(贪心算法)
贪心思想用尽可能最小的成本解决最大的问题解法1:class Solution { public int findContentChildren(int[] g, int[] s) { Arrays.sort(g); Arrays.sort(s); int count = 0; int length1 = g.length; int length2 = s.length; for (int i =原创 2020-12-25 10:33:07 · 676 阅读 · 0 评论 -
动态规划笔记
什么是动态规划?按照动态规划传统的说法就是,将一个大问题分解成一个小问题,然后分别对各个小问题分别求解,最后整合到一起就是动态规划。按照解题的思路来看,一般求总共有多少种方式的题型属于动态规划题型(计数型动态规划求方式数),求一个完整的过程的属于递归题型(打印出所有的解一般不是动态规划做的事情)动态规划提醒的特点:计数求最大最小(并不是说求最大最小一定就是用动态规划来做,但是有极大的可能使用动态规划来做,有时候用贪心算法也是用来求最大最小值的)。求存在性先看下面的这道交换硬币的题正常原创 2020-12-18 21:12:47 · 998 阅读 · 0 评论 -
最大整数排列
问题描述:设有n个正整数,将他们连接成一排,组成一个最大的多位整数package oj;import java.math.BigInteger;import java.util.Arrays;import java.util.Collections;import java.util.Scanner;public class MaxArray{// public static Number[] result; public static void main(String[] arg原创 2020-11-29 22:52:06 · 150 阅读 · 0 评论 -
算法训练:简化路径(栈)
思路:从题目的出发,一个输入的路径包含5种东西,第一个是路径信息,即大小写的字母a,b,c,第二种是"…“用来指代上级目录,第三种是”.",第四种是"/",第五种是空字符"",而输出的路径是/加上路径信息,所以另外的3中东西用于判断是否需要将路径信息入栈出栈。步骤:①将输入的字符串用String类自带的split方法,用"/“将字符串分割,并存放到一个数组中,此时的数组中包含的元素就是以上5种情况的组合。②遍历数组,对数组中的元素进行判断,如果是栈不空的情况下,且遇到”…",即返回上级目录,因此要..原创 2020-10-06 13:20:09 · 185 阅读 · 0 评论 -
算法训练:相同的树 java
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) {..原创 2020-09-11 20:47:58 · 81 阅读 · 0 评论 -
算法训练:重复的子字符串(KMP)java
问题描述在用KMP算法实现该问题前先说明以下什么是KMP算法,以及KMP算法的常规实现是怎样的。KMP算法:首先先看一组例子,上面为主串,下面为模式串由图中可以看到,模式串的前五个字符和主串的前五个字符是相同的,即匹配的,而第六个开始,主串与模式串的字符开始不同。那么这个时候,开始看模式串前五位中的最大公共前缀是啥,如下图所示:这个时候我们可以发现,模式串中最长的可以与主串相匹配的子串为GTG,因此接下来,我们可以移动模式串,将模式串中匹配的最大前缀子串向右移动,移到和主串中的三个相互匹配原创 2020-08-27 19:30:36 · 568 阅读 · 0 评论 -
算法训练:电话号码的字母组合(回溯求解)java
问题描述:分析问题:由问题可知,每一个按键都有着对应得映射关系,因此可以将按键的值作为key,将对应的小写字母字符串作为值存放在哈希表中。通过访问按键的值对相应的字符串的逐个字符进行遍历,采用深度遍历的思想,将访问到的字符进行组合,并将组合的结果存放在一个数组中,每一个组合完成之后将数组加入一个集合之中,最后返回该存放了不同值的集合。代码如下:class Solution { public List<String> letterCombinations(String digi原创 2020-08-26 12:38:07 · 195 阅读 · 0 评论 -
算法训练:二进制手表(暴力、回溯求解)java
问题描述二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。给定一个非负整数 n 代表当前 LED 亮着的数量,返回所有可能的时间。解法一:暴力求解利用两个for循环可以得到从0:00到11:59之间的所有时间,根据手表的特性,上方有LED的亮灯数表示了该时间所对应的二进制数有多少个1,因此可以采用java语法中Integer的方法bitCount,该方法可以返回一个整数转二进制后1的个数,当上方转载 2020-08-25 22:46:04 · 676 阅读 · 0 评论 -
算法训练:两数之和(暴力法、哈希表法)java实现
题目描述1:暴力法(直接采用双重for循环寻找)class Solution { public int[] twoSum(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[j] == target - nums[i]) {原创 2020-08-23 17:00:00 · 438 阅读 · 0 评论