MySQL
存储过程
格式化日期: %Y 四位数年,%M 英语月份,%D日期
DELIMITER //
CREATE PROCEDURE formate_date(IN day1 DATE, OUT result VARCHAR(50))
BEGIN
SELECT DATE_FORMAT(day1, "%Y年%M月%D日") INTO result;
END //
DELIMITER;
调用存储过程: 关键是要加SET, 然后变量前加@
SET @day1 = '1992-08-09';
CALL formate_date(@day1, @res);
SELECT @res
删除存储过程/表
drop function/procedure if exists (namexxxx)
存储函数的构建:输入部门名字,得出部门的平均工资
DELIMITER //
CREATE FUNCTION dept_sal(iname VARCHAR(30))
RETURNS INT
DETERMINISTIC
CONTAINS SQL
BEGIN
RETURN (
SELECT AVG(e.salary)
FROM employees e JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_name = iname
);
END //
DELIMITER;
面向对象
可以不用static直接呼出方法:
新建一个这个class(比如Solution s = new Solution()),然后用这个class内置的方法(比如s.func(xx))
面向对象的内存解析
运行时的数据区:
- Heap, 存放对象实例
- Stack,存储局部变量
- Method Area, 方法区,存储已经被VM加载的类信息、常量、静态变量、即时编译器编译后的代码
变量
属性(局部变量)vs 成员变量
局部变量在新建时有默认值,但是成员变量没有,也不能在前面加修饰词
强制转移
int 向下取整
Math.random() 从[0, 1)
算法
并查集优化
QuickFind
QuickUnion
权重,根据权重去Union,权重小的root被加到权重大的上。
// To do;
贪心
1217 玩筹码
分两步
- 把奇数和偶数都放到1和0,这就是贪心,每一步都取最优解,即cost = 0
- 再1和0中取个最小值
class Solution {
public int minCostToMoveChips(int[] position) {
int odd = 0, even = 0;
for (int n: position) {
if (n % 2 == 0) {
even++;
} else {
odd++;
}
}
return Math.min(odd, even);
}
}
55 Jump Game
最主要看的不是它怎么到,不是一个一个的去枚举,而是直接算当前这个数能到达的范围。
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 1) {
return true;
}
int coverRange = 0;
for (int i = 0; i <= coverRange; i++) {
coverRange = Math.max(coverRange, i + nums[i]);
/* i + nums[i] 即为当前的数从当前出发能到达的范围,比如num[0] = 3, 那么
从nums[0]出发,最远就能到num[3].
*/
if (coverRange >= nums.length - 1) {
return true;
}
}
return false;
}
}
记忆搜索 Memorization
保存已经计算过的值,然后再下一次搜索中如果碰到这个值可以直接调用
比如斐波那契数列中的构建array就比递归快。同理,这道零钱兑换,也比递归快
如果是用递归,加一个count去数,每一次就是 amount-count,那就会空间超时
- 322 零钱兑换
Input: coins = [1,2,5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
class Solution {
private int[] bucket;
public int coinChange(int[] coins, int amount) {
if (amount == 0) {
return 0;
} else if (coins.length == 0) {
return -1;
}
bucket = new int[amount];
return getMinCount(coins, amount);
}
private int getMinCount(int[] coins, int amount) {
if (amount < 0) {
return -1;
} else if (amount == 0) {
return 0;
}
//记忆化处理就是储存进一个数组
if (bucket[amount - 1] != 0) {
return bucket[amount - 1];
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < coins.length; i++) {
int coin = coins[i];
// 剩余的amount里最小能拿出来的次数
int restMinCount = getMinCount(coins, amount - coin);
if (restMinCount >= 0 && restMinCount < min) {
min = restMinCount + 1;
// 这个加1,就是加上现在拿的这一次
}
}
//在这个amount上,比如说amount = 8,那么Index就是7,在这个数组的位置上储存最小的能取到的值.
//如果是MAX_VALUE,那么证明拿不到想要的target,即是-1.
bucket[amount - 1] = (min == Integer.MAX_VALUE ? -1 : min);
return bucket[amount - 1];
}
}
动态规划
动态规划的要点即是找规律:从初始状态,到最终结果,中间需要有一个过程的产生,所以最主要的就是摸清楚这个产生这个过程的方程或者函数。
这不同路径这题里面就是
上面的格的个数 + 右面的格的个数 = 当前这个格能到达的路径数
- 62 不同路径
class Solution {
public int uniquePaths(int m, int n) {
int[][] grid = new int[m][n];
for (int i = 0; i < m; i++) {
grid[i][0] = 1;
}
for (int i = 0; i < n; i++) {
grid[0][i] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
grid[i][j] = grid[i-1][j] + grid[i][j-1];
}
}
return grid[m-1][n-1];
}
}