链表 返回链表的倒数第k个节点 题目要求是ACM模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import java.util.*;public class Main { static final int N = (int ) (1e5 + 10 ); static int dummy = -1 , idx = 0 ; static int [] e = new int [N]; static int [] ne = new int [N]; static cur = 0 ; static void insert (int k,int v) { e[idx] = v; ne[idx] = ne[k]; ne[k] = idx++; cur++; } static void remove (int k) { ne[k] = ne[ne[k]]; cur--; } static void print () { System.out.println("xxx" ); for (int i = ne[dummy]; i != -1 ; i = ne[i]){ System.out.printf("%d " ,e[i]); } } public static void main (String[] args) { e[idx] = 0 ; ne[idx] = dummy; dummy = idx++; for (int i = 0 ; i <= 10 ; i++){ insert(i,i); } Scanner sc = new Scanner (System.in); int k = sc.nextInt(); remove(cur - k); print(); } }
扩展完整单链表模板https://www.acwing.com/problem/content/description/828/
写法1: 哑节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 import java.util.*;public class Main { static int N = (int ) (1e5 + 10 ); static int dummy = -1 ,idx = 0 ; static int [] e = new int [N]; static int [] ne = new int [N]; static void insert (int k,int v) { e[idx] = v; ne[idx] = ne[k]; ne[k] = idx++; } static void remove (int k) { ne[k] = ne[ne[k]]; } static void print () { int u = dummy; for (int i = ne[u]; i != -1 ; i = ne[i]){ System.out.printf("%d " ,e[i]); } } public static void main (String[] args) { e[idx] = 0 ; ne[idx] = dummy; dummy = idx++; Scanner sc = new Scanner (System.in); int m = sc.nextInt(); while (m > 0 ){ m--; String s = sc.next(); char op = s.charAt(0 ); if (op == 'H' ){ int v = sc.nextInt(); insert(0 ,v); }else if (op == 'D' ){ int k = sc.nextInt(); remove(k); }else { int k = sc.nextInt(); int v = sc.nextInt(); insert(k,v); } } print(); } }
写法2:头插法 这种头插法也要掌握 因为图论中实际上用的是头插法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 import java.util.*;public class Main { static final int N = (int ) (1e5 + 10 ); static int [] e = new int [N]; static int [] ne = new int [N]; static int head = -1 ,idx = 0 ; static void add_head (int v) { e[idx] = v; ne[idx] = head; head = idx++; } static void insert (int k,int v) { e[idx] = v; ne[idx] = ne[k]; ne[k] = idx++; } static void remove (int k) { ne[k] = ne[ne[k]]; } static void print () { for (int i = head ; i != -1 ; i = ne[i]){ System.out.printf("%d " ,e[i]); } } public static void main (String[] args) { Scanner sc = new Scanner (System.in); int m = sc.nextInt(); while (m > 0 ){ m--; String s = sc.next(); char op = s.charAt(0 ); if (op == 'H' ){ int v = sc.nextInt(); add_head(v); }else if (op == 'D' ){ int k = sc.nextInt(); if (k == 0 ){ head = ne[head]; }else { remove(k - 1 ); } }else { int k = sc.nextInt(); int v = sc.nextInt(); insert(k - 1 ,v); } } print(); } }
二分 树 剑指offer26 树的子结构 DFS
原题链接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import java.util.*;public class Solution { boolean dfs (TreeNode a,TreeNode b) { if (b == null ){ return true ; } if (a == null ){ return false ; } if (a.val != b.val){ return false ; } return dfs(a.left,b.left) && dfs(a.right,b.right); } public boolean HasSubtree (TreeNode root1,TreeNode root2) { if (root1 == null || root2 == null ){ return false ; } return dfs(root1,root2) || HasSubtree(root1.left,root2) || HasSubtree(root1.right,root2) ; } }
leetcode112 路径总和 DFS
原题链接:https://leetcode.cn/problems/path-sum/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { public boolean hasPathSum (TreeNode root, int targetSum) { if (root == null ){ return false ; } if (root.left == null && root.right == null ){ return root.val == targetSum; } return hasPathSum(root.left,targetSum - root.val) || hasPathSum(root.right,targetSum - root.val); } }
排序 自命题 数组找中位数 (要自己实现排序算法 其实就是快排) 1 2 3 Class Main () { public }
DP leetcode518 零钱兑换II 抖音支付二面
完全背包问题
原题链接https://leetcode.cn/problems/coin-change-ii/
朴素解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { final int N = 5010 ; int [][] f = new int [N][N]; public int change (int amount, int [] coins) { int n = coins.length; f[0 ][0 ] = 1 ; for (int i = 1 ; i <= n; i++){ int val = coins[i - 1 ]; for (int j = 0 ; j <= amount ; j++){ f[i][j] = f[i - 1 ][j]; for (int k = 1 ; k * val <= j ; k++){ f[i][j] += f[i - 1 ][j - k * val] ; } } } return f[n][amount]; } }
从体积开始倒退 f[j] 可以由无数个之前的f[j - 1]的可能转移而来 优化写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { final int N = 5010 ; public int change (int amount, int [] coins) { int [] f = new int [N]; f[0 ] = 1 ; for (int i = 1 ; i <= coins.length ; i++){ int v = coins[i - 1 ]; for (int j = v ; j <= amount ; j++){ f[j] += f[j - v]; } } return f[amount]; } }
leetcode518 零钱兑换I 非面试 但差不多 也有可能考 完全背包求方案数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { int INF = 0x3f3f3f3f ; final int N = (int )(1e4 + 10 ); int [] f = new int [10010 ]; public int coinChange (int [] coins, int amount) { if (amount == 0 ){ return 0 ; } int n = coins.length; Arrays.fill(f,INF); for (int i = 1 ; i <= amount ; i++){ f[i] = INF; } for (int i = 1 ; i <= n ; i++){ int v = coins[i - 1 ]; if (v <= amount){ f[v] = 1 ; } for (int j = v ; j <= amount ; j++ ){ f[j] = Math.min(f[j],f[j - v] + 1 ); } } return f[amount] == INF ? -1 : f[amount]; } }
DFS leetcode39 组合回溯 抖音支付一面
原题链接:https://leetcode.cn/problems/combination-sum/description/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution { int target; int n; int [] q; List<List<Integer>> ans = new ArrayList <>(); public List<List<Integer>> combinationSum (int [] candidates, int target) { q = candidates; this .target = target; this .n = candidates.length; Arrays.sort(candidates); dfs(new ArrayList <>(),0 ,0 ); return ans; } void dfs (List<Integer> list,int cur,int id) { if (cur == target){ ans.add(new ArrayList <>(list)); } if (cur > target){ return ; } for (int i = id; i < n ; i++){ list.add(q[i]); cur += q[i]; dfs(list,cur,i); list.remove(list.size() - 1 ); if (cur > target){ return ; } cur -= q[i]; } } }
字典树 leetcode1268 搜索推荐系统 原题链接:https://leetcode.cn/problems/search-suggestions-system/description/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { int [][] tr = new int [20010 ][26 ]; int idx = 0 ; Map<Integer, Integer> min = new HashMap <>(), max = new HashMap <>(); void add (String s, int num) { int p = 0 ; for (int i = 0 ; i < s.length(); i++) { int u = s.charAt(i) - 'a' ; if (tr[p][u] == 0 ) { tr[p][u] = ++idx; min.put(tr[p][u], num); } max.put(tr[p][u], num); p = tr[p][u]; } } int [] query(String s) { int a = -1 , b = -1 , p = 0 ; for (int i = 0 ; i < s.length(); i++) { int u = s.charAt(i) - 'a' ; if (tr[p][u] == 0 ) return new int []{-1 , -1 }; a = min.get(tr[p][u]); b = max.get(tr[p][u]); p = tr[p][u]; } return new int []{a, b}; } public List<List<String>> suggestedProducts (String[] ps, String w) { Arrays.sort(ps); List<List<String>> ans = new ArrayList <>(); for (int i = 0 ; i < ps.length; i++) add(ps[i], i); for (int i = 0 ; i < w.length(); i++) { List<String> list = new ArrayList <>(); int [] info = query(w.substring(0 , i + 1 )); int l = info[0 ], r = info[1 ]; for (int j = l; j <= Math.min(l + 2 , r) && l != -1 ; j++) list.add(ps[j]); ans.add(list); } return ans; } }
SQL SQL156 各个视频的平均完播率 原题链接:https://www.nowcoder.com/practice/96263162f69a48df9d84a93c71045753?tpId=268&tqId=2285032&ru=/exam/oj&qru=/ta/sql-factory-interview/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DSQL%25E7%25AF%2587%26topicId%3D268
1 2 3 4 5 6 7 8 9 10 11 # 计算2021 年里有播放记录的每个视频的完播率(结果保留三位小数),并按完播率降序排序 # 拆解条件2021 年 完播率 降序排序 # 完播率 = 视频完播次数 / 总播放数 select a.video_id , round(sum (if(end_time - start_time >= duration,1 ,0 ))/ count (start_time),3 ) as avg_comp_play_rate from tb_user_video_log as aleft join tb_video_info as bon a.video_id = b.video_idwhere year (start_time) = 2021 group by a.video_idorder by avg_comp_play_rate desc ;