- 博客(78)
- 收藏
- 关注
原创 JAVA基础
深拷贝 设计模式 Hashtable和HashMap的区别 String,Stringbuffer,StringBuilder java8特性 重写equals方法还需重新hashcode方法
2021-08-27 15:21:44
136
原创 数据库学习
数据库三大范式 确保每列原子性,所有字段值都是不可分解的原子值 每行数据都能区分,选择合适的主键 每一个表不能包含其他表的分主键信息 MySQL基本机构: Server层 链接器:身份认证 查询缓存:执行查询语句的时候,会先查缓存(MySQL 8.0 版本后移除,表的更新会使缓存清空,且有更好的,例如redis) 分析器:对SQL语句进行分析,分析语句的方式,查询的表和字段,查询条件等,检查SQL语句是否正确 优化器:按照MYSQL认为最优的方案执行(例如多个索引,多
2021-08-09 20:55:14
197
原创 多线程多进程
基本概念: 进程:执行程序的一次执行过程,是系统进行资源分配和调度的基本单位,其中,程序是指令和数据的有序集合 线程:CPU调度和执行的单元,最小的处理单元 进程和线程之间的关系: 一个进程可以有多个线程 资源分配给进程,同一进程的所有线程共享进程的所有资源 CPU运行的是线程 并发和并行: 并行:同一时刻,多个任务同时执行 并发:执行多个任务,能顺利的来回切换。并发包含并行 多核CPU能够支持多线程并行执行,单核CPU只能支持多线程的并发执行
2021-08-04 17:34:50
188
原创 JVM学习
JVM类加载过程 加载>>链接>>初始化 何时需要进行类加载: new 一个对象的时候 调用对象静态变量或者静态方法 反射调用类 初始话子类的时候,若父类没有被初始化,则也会执行父类的初始化 程序启动时,main方法所在类 加载过程: 通过类的全限定名(所在包名 + 类名)来获得此类的二进制字节码流 将这些静态数据转换为方法区中的运行时数据 在方法区中生这个类对应的java.lang.Class对象,作为调用此类各种信息的.
2021-07-30 15:17:19
81
原创 各种常见的排序算法
冒泡排序: 对数组进行操作,第一次第一个元素到倒数第二个元素进行遍历,每次将当前元素与后一个元素进行比较,如果结果不符合排序规则,则将两个元素交换位置。第一次遍历以后,最大(小)元素交换到了最后,下一次,从第一个元素到倒数第三个元素进行遍历。 时间复杂度:O(n^2) 空间复杂度:O(1) 是否稳定:是 插入排序: 基本思想就是将一个元素,插入已经排过序的数组中。例如在进行第i此遍历时,数组前i-1个元素已经有序,此时将第i个元素插入有序数组中的对应位置,其他元素依次向后移动 时间
2021-07-29 11:41:43
104
原创 Spring学习
常用依赖<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/b.
2021-06-10 11:33:13
52
原创 剑指Offer 56
[1,2,10,4,1,4,3,3]使用位运算,首先将数组所有元素异或运算,因为想x^x=0;所有最后的结果为只出现一次的两个数的异或结果,例:2^10;然后选取这两个数中一个位置相同值不同的值,例:2 :10, 10: 1010,其结果为1000。计算方法为,2^10结果莫一位结果为1的值x:1000然后使用x与数组相与,判断是否为0 ,以此将数组分为两部分,其中一部分包含10,另一部分包含2[1,2,4,1,4,3,3], [10],分别对这两个数组进行异或运算即为结果...
2021-04-23 10:57:34
78
原创 剑指Offer 52
方法一:使用两个栈,将两个链表进栈,出栈时,选最后一个相同的节点public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { Stack<ListNode> stack_1 = new Stack<>(); Stack<ListNode> stack_2 = new Stack<>();
2021-04-21 15:45:52
71
原创 剑指Offer 51
使用归并排序class Solution { public int reversePairs(int[] nums) { if(nums.length <= 1) return 0; int i = 0; int k = 1; int sum = 0; while(k < nums.length){ sum += gb(nums, i, k); if(i
2021-04-21 15:20:26
43
原创 剑指Offer 49
使用数组dp记录已经出现的丑数,分别记录2,3,5需要相乘的数组的下标index_1, index_2,index_3。选择dp[index_1] * 2,dp[index_2] * 3,dp[index_3] * 5 最小值作为新的元素加入dp中,并将对应的一个下标或两个下标向后移动一位(+1);class Solution { public int nthUglyNumber(int n) { int[] dp = new int[n]; dp[0]..
2021-04-20 14:51:33
45
原创 剑指Offer 48
设置初始位置为0,记录出现的字符,每次出现已经被记录的字符时,使用此时的下标到初始位置的距离与最大值比较,大于则替换,并更改初始位置为上一次此字符的位置class Solution { public int lengthOfLongestSubstring(String s) { Map<Character, Integer> hashmap = new HashMap<>(); int sum = 0, index = 0;
2021-04-20 14:45:24
57
原创 剑指Offer 47
因为只会向右向下移动,所有从左到右,从上到下遍历棋盘,更新每个位置的值为可能最大值(加上右或者上位置的值)注意边界位置class Solution { public int maxValue(int[][] grid) { int m = grid.length; int n = grid[0].length; for(int i = 1; i < n; i++) grid[0][i] += grid[0][i
2021-04-16 16:07:52
40
原创 剑指Offer 46
动态规划将数值变为字符串,依次遍历,每次遍历字符时,观察其前面一个字符的值例如:xxxx12xxxx 当遍历到2时,dp(xxxx)和dp(xxxx1)的结果已知,则dp(xxxx12) =dp(xxxx) +dp(xxxx1),因为其可以有两种表达形式xxxx1 2和xxxx 12xxxx27xxxx 当遍历到7时,dp(xxxx)和dp(xxxx1)的结果已知,则dp(xxxx27) =dp(xxxx1),因为其表示形式只能是xxxx2 7,不存在xxxx 2...
2021-04-16 11:20:05
509
原创 剑指Offer 45
首先将数字变为字符串然后进行排序,自定义排序规则:字符串X,Y进行排序时比较X + Y < Y + X ? (X,Y) : (Y,X)class Solution { public String minNumber(int[] nums) { String[] strs = new String[nums.length]; for(int i = 0; i < nums.length; i++){ strs[i] = St
2021-04-16 10:37:13
43
原创 剑指Offer 44
首先确定,n 所对应的是几位数(如xxxx),然后确定第一个1000的起始位置m,然后使用(n - m) / 4(位数) + 1000,确定是哪一个确定的数,并用 4 -(n - m) % 4记录这个数从后往前第几位注:注意整型的内存范围,可以使用long代替class Solution { public int findNthDigit(int n) { if(n <= 9) return n; long m = n ++; lon.
2021-04-14 16:07:15
52
原创 剑指Offer 43
将函数用 get(num)表示则可以分为3种情况:1. 2xx 表示为2 * get(99) + 100 + get(xx) 其中 2 * get(99)为200以下个位和十位数值的1的个数和 100表示百位数值(100 ~ 199) get(xx) 表示201 到 2xx 之间个位和十位的1个数和2. 1xx 表示为1 * get(99) + (xx + 1) + get(xx) 同上 (xx + 1)表示百位数值1的个数3. 0xx 表示为 get(x...
2021-04-14 11:33:08
154
原创 剑指Offer 42
贪心算法:每次累加求和,当之前数据的和是小于0时,就不计算之前的和,和从0开始计算并在当和大于最大值时,更新最大值class Solution { public int maxSubArray(int[] nums) { int sum = nums[0]; int max = sum; for(int i = 1; i < nums.length; i++){ if(sum < 0)
2021-04-14 09:42:18
71
原创 剑指Offer 40
使用优先队列,将非负数变为非正数存储,结果变成非负数class Solution { public int[] getLeastNumbers(int[] arr, int k) { if(k == 0) return new int[0]; int[] nums = new int[k]; Queue<Integer> queue = new PriorityQueue<>(); for(int i =
2021-04-07 15:40:13
105
原创 剑指Offer 39
方法一:随机选择一个数,遍历整个数组看这个数是否是众数class Solution { public int majorityElement(int[] nums) { int number = nums.length; int num = 0; int item = -1; while(num <= number / 2){ item = nums[(int)(Math.random() * n
2021-04-07 15:11:54
53
原创 剑指Offer 38
首先将字符串变为字符数组并排序使用递归,在每次递归中,遍历字符数组中没有做标记的元素,加到字符串中,并将字符数组的元素做标记,递归,并在递归结束时,撤销标记,并删除字符串最后一个元素;注:考虑字符数组中有相同元素当字符数组所有元素均做了标记以后就将字符串加入字符串数组class Solution { List<String> str_s; char[] new_s; StringBuilder res; public String[] perm
2021-04-07 12:01:23
78
原创 剑指Offer 37
序列化:使用队列储存每个节点反序列化:使用队列和指针,指针指向队列首节点的左子树,然后指针向后移动一次,指针指向队列首节点的右子树,出队列并指针+1,此时指针又指向队列首节点的左子树;队列只存储有值得树public class Codec { // Encodes a tree to a single string. public String serialize(TreeNode root) { if(root == null) return "[]";
2021-04-07 11:18:28
105
原创 剑指Offer 36
中序遍历,使用两个指针,一个指针指向元素最小的节点(头节点),另一个指针指向当前遍历的节点(尾节点)class Solution { Node start = null; Node end = null; public Node treeToDoublyList(Node root) { if(root == null) return root; dfs(root); end.right= start; start
2021-04-02 15:26:47
71
原创 剑指Offer 35
使用HashMap存储原链表中每个节点的位置遍历两次,第一次仅仅依靠next 复制链表第二次,依靠HashMap建立random链接class Solution { public Node copyRandomList(Node head) { if(head == null) return null; Map<Node, Integer> hashmap = new HashMap<>(); List<No
2021-04-02 14:44:58
100
原创 剑指Offer 33
使用递归,传递的参数为数组左右边界,右边界即为跟节点,数组前半部分值必小于跟节点所对应的值,数组后半部分值必大于根节点指。固从后往前遍历,找到第一个小于跟节点的值,且之前的所有值均是小于根节点指的,否则就二叉搜索树的后序遍历结果。并以此为边界分割数组(既分割为左右子树)class Solution { public boolean verifyPostorder(int[] postorder) { return dfs(postorder, 0, postorder.le
2021-04-01 15:24:12
57
原创 剑指Offer 32
用队列储存每个不为空的节点class Solution { public int[] levelOrder(TreeNode root) { if(root == null) return new int[]{}; Queue<TreeNode> queue = new LinkedList<>(); List<Integer> list = new ArrayList<>(); q
2021-04-01 14:26:32
49
原创 剑指Offer 31
方法一使用栈和指针,首先指针为入栈的第一个位置i,当出栈为莫一个值时,说明入栈队列在这个值之前的所有值均入栈,因此将此值在入栈队列对应的下标j到指针i中的所有下标[1, j)入栈。更新指针i = j + 1;注;此时就j > i;若i > j, 表明,j对应值已经入栈,之间将其与栈的顶元素相比较,不相同则返回false;class Solution { public boolean validateStackSequences(int[] pushed, int[] pop
2021-04-01 11:09:08
75
原创 剑指Offer 29
一层一层遍历,每一层顺时针遍历四边class Solution { public int[] spiralOrder(int[][] matrix) { int m = matrix.length; if(m == 0) return new int[]{}; int n = matrix[0].length; if(n == 0) return matrix[0]; int dp = 0; int
2021-03-30 17:30:07
95
原创 剑指Offer 28
递归,判断左子树的左子树与右子树的右子树是否相同,左子树的右子树与右子树的左子树是否相同class Solution { public boolean isSymmetric(TreeNode root) { if(root == null) return true; return dfs(root.left, root.right); } private boolean dfs(TreeNode root_left, TreeNode roo
2021-03-30 16:51:07
90
原创 剑指Offer 27
交换左右子树class Solution { public TreeNode mirrorTree(TreeNode root) { if(root == null) return root; TreeNode left = root.left; root.left = mirrorTree(root.right); root.right = mirrorTree(left); return root; }
2021-03-30 16:42:31
83
原创 剑指Offer 26
分成两部第一步在A树中寻找与B根节点值相同的节点;第二步比较A树中是否包含B树结构class Solution { public boolean isSubStructure(TreeNode A, TreeNode B) { if(B == null) return false; return isSub(A, B); } private boolean isSub(TreeNode A, TreeNode B){ i
2021-03-30 16:38:33
52
原创 剑指Offer 25
注意,可能存在空链表使用头节点数值小的作为需返回的链表将另外一个链表的节点加入需返回的链表class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if(l1 == null) return l2; if(l2 == null) return l1; if(l1.val > l2.val){ ListNode item
2021-03-30 16:21:53
51
原创 剑指Offer 24
递归,使用全局变量表示当前的尾节点class Solution { ListNode start; public ListNode reverseList(ListNode head) { if(head == null) return head; if(head.next == null) { start = head; return head; } ListNode no
2021-03-30 16:10:06
43
原创 剑指Offer 22
双指针,两个指针间隔K个节点,当前面的指针为空时,另一个指针既为答案class Solution { public ListNode getKthFromEnd(ListNode head, int k) { ListNode left = head; for(int i = 0; i < k; i++) left = left.next; ListNode right = head; while(l
2021-03-30 15:50:41
61
原创 剑指Offer 21
双指针,一个指针指向(前面需保存奇数的位置),另一个指针每次+1,当次指针所指数字为奇数时,就与另一个指针所指位置的元素互换class Solution { public int[] exchange(int[] nums) { int i= 0; for(int j = 0; j < nums.length; j++){ if(nums[j] % 2 == 1){ int item = nums[i
2021-03-30 15:36:47
78
原创 剑指Offer 20
需要考虑多种情况1. 字符串两边有多余的空格2. 小数可以没有整数部分或者小数部分3. e(E)前面必须包含整数或者小数4. 注意边界class Solution { public boolean isNumber(String s) { int i = 0; int len = s.length(); //去除两边的空格 if(len == 0) return false; while(s.ch
2021-03-30 15:32:35
46
原创 剑指Offer 19
运用动态规划,创建二维数组,表示dp[i][j] 表示 s前i个字符与,p中前j个字符 相匹配的结果考虑特殊字符*:如果p[j] = '*',dp[i][j] =dp[i][j - 2],如果s[i -1]==p[j-1]或者p[j-1]='.',则dp[i][j] =dp[i - 1][j] |dp[i][j - 2];例:s="aaa",p="a*""aaa"与"a*"是否想匹配,可以由"aa"与"a*","aaa"与"a"相匹配决定,而"aa"与"a*"是否匹配,也可以由"a"与...
2021-03-29 17:59:25
120
原创 剑指Offer 17
判断节点的下一个节点是否为空或节点下一个节点 的值是否等于给定值class Solution { public ListNode deleteNode(ListNode head, int val) { if(head == null) return head; if(head.val == val) return head.next; ListNode node = head; while(node.next != null &
2021-03-29 15:25:37
46
原创 剑指Offer 17
遍历class Solution { public int[] printNumbers(int n) { n = (int)Math.pow(10, n) - 1; int[] number = new int[n]; for(int i =0; i < n; i ++) number[i] = i + 1; return number; }}
2021-03-29 14:59:23
40
原创 剑指Offer 16
快速求幂求幂的时候不用一次一次相乘,可以每次平方,并将幂除以2例如:具体来说2的10次方,可以变换为:4的5次方4 * 4的4次方4 * 16的2次方4 * 256的一次方class Solution { public double myPow(double x, int n) { if(n == 0) return 1.0; //直接负最小值,变换成正最大值会出错,范围不一样 long new_n = n
2021-03-29 12:10:49
89
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人