queue.add(root); while (!queue.isEmpty()){ int size=queue.size(); List<Integer> temp=new ArrayList<>(); for (int i = 0; i < size; i++) { TreeNode poll = queue.poll(); temp.add(poll.val); if (poll.left!=null)queue.offer(poll.left); if (poll.right!=null)queue.offer(poll.right); } res.add(temp); }
dfs=栈,压栈,出栈 一次访问多条路径;
1 2 3 4 5 6 7
//递归 public static void helper(TreeNode root,List<Integer>res) { if (root == null) return; res.add(root.val); helper(root.left,res); helper(root.right,res); }
public static void heapsort(int[] tree, int n) { build_heap(tree, n); for (int i = n - 1; i >= 0; i--) { swap(tree, i, 0); heapify(tree, i, 0); } }
public static void build_heap(int[] nums, int n) { int last = n - 1; int par = (last - 1) / 2; for (int j = par; j >= 0; j--) { heapify(nums, n, j); } }
public static void heapify(int[] nums, int n, int i) { if (i >= n) return; int c1 = 2 * i + 1; int c2 = 2 * i + 2; int max = i; if (c1 < n && nums[c1] > nums[max]) { max = c1; } if (c2 < n && nums[c2] > nums[max]) { max = c2; } if (max != i) { swap(nums, i, max); heapify(nums, n, max); } }
时间复杂度
一.初始化建堆 初始化建堆只需要对二叉树的非叶子节点调用 build_heap()函数,由下至上,由右至左选取非叶子节点来调用函数。那么倒数第二层的最右边的非叶子节点就是最后一个非叶子结点。 假设高度为 k,则从倒数第二层右边的节点开始,这一层的节点都要执行子节点比较然后交换(如果顺序是对的就不用交换);倒数第三层呢,则会选择其子节点进行比较和交换,如果没交换就可以不用再执行下去了。如果交换了,那么又要选择一支子树进行比较和交换;高层也是这样逐渐递归。 那么总的时间计算为:s = 2^( i - 1 ) * ( k - i );其中 i 表示第几层,2^( i - 1) 表示该层上有多少个元素,( k - i) 表示子树上要下调比较的次数。 S = 2^(k-2) * 1 + 2^(k-3)2……..+2(k-2)+2^(0)*(k-1) ===> 因为叶子层不用交换,所以 i 从 k-1 开始到 1; S = 2^k -k -1;又因为 k 为完全二叉树的深度,而 log(n) =k,把此式带入; 得到:S = n - log(n) -1,所以时间复杂度为:O(n)
private static void quicksort(int[] nums, int left, int right) { if (left >= right) return; int pindex = partition(nums, left, right); quicksort(nums, left, pindex - 1); quicksort(nums, pindex + 1, right); }
private static int partition(int[] nums, int left, int right) { Random r = new Random(); int rindex = left + r.nextInt(right - left + 1); swap(nums, rindex, left);
int pivot = nums[left]; int l = left; for (int i = left + 1; i <= right; i++) { if (nums[i] < pivot) { l++; swap(nums, i, l); } } swap(nums, left, l); return l; }
private static void mergesort(int[] nums, int left, int right, int[] temp) { if (left>=right)return; int mid=left+(right-left)>>1; mergesort(nums, left,mid,temp); mergesort(nums,mid+1,right,temp); //数组有序,不用merge if (nums[mid]<=nums[mid+1]){ return; } merge(nums,left,mid,right,temp); }
private static void merge(int[] nums, int left, int mid, int right, int[] temp) { //System.arraycopy(nums,left,temp,left,right-left+1); for (int i = left; i <= right; i++) { temp[i]=nums[i]; } //左右两半的起点 int i=left; int j=mid+1; for (int k = left; k <= right; k++) { if (i==mid+1)nums[k]=temp[j++]; else if (j==right+1)nums[k]=temp[i++]; else if (temp[i]<=temp[j])nums[k]=temp[i++]; else nums[k]=temp[j++]; } }
//递归版本 public static List<Integer> preorder2(TreeNode root){ List<Integer> res = new ArrayList<>(); helper(root,res); return res; } public static void helper(TreeNode root,List<Integer>res) { if (root == null) return; res.add(root.val); helper(root.left,res); helper(root.right,res); }
public static void preorder(TreeNode root){ if (root==null)return; System.out.print(root.val+" "); preorder(root.left); preorder(root.right); } //迭代统一写法 public static List<Integer> preorder3(TreeNode root){ List<Integer> res=new ArrayList<>(); if (root==null)return res; Stack<TreeNode> stack=new Stack<>(); stack.push(root); while (!stack.isEmpty()){ TreeNode top = stack.peek(); if (top!=null){ stack.pop(); if (top.right!=null)stack.push(top.right); if (top.left!=null)stack.push(top.left); stack.push(top); stack.push(null); }else{ stack.pop(); TreeNode pop = stack.pop(); res.add(pop.val); } } return res; }
层序遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
public static List<List<Integer>> levelorder(TreeNode root){ if (root==null)return null; List<List<Integer>>res=new ArrayList<>(); LinkedList<TreeNode> queue=new LinkedList<>(); queue.add(root); while (!queue.isEmpty()){ int size=queue.size(); List<Integer> temp=new ArrayList<>(); for (int i = 0; i < size; i++) { TreeNode poll = queue.poll(); temp.add(poll.val); if (poll.left!=null)queue.offer(poll.left); if (poll.right!=null)queue.offer(poll.right); } res.add(temp); } return res; }
右视图-只需要判断一下是否是最后一个。
1 2 3 4 5 6 7
for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); if (node.left != null) queue.offer(node.left); if (node.right != null) queue.offer(node.right); if (i == size - 1) //将当前层的最后一个节点放入结果列表 res.add(node.val); }
public static List<List<Integer>> levelOrder(Node root) { List<List<Integer>> res = new ArrayList<>(); Deque<Node> que = new LinkedList<>(); if (root == null) return res; que.offer(root); while (!que.isEmpty()) { int size = que.size(); List<Integer> temp = new ArrayList<>(); for (int i = 0; i < size; i++) { Node poll = que.poll(); temp.add(poll.val);
List<Node> children = poll.children; if (children == null || children.size() == 0) { continue; } for (Node child : children) { if (child != null) que.offer(child); } } res.add(temp); } return res; }
class Node { public int val; public List<Node> children; public Node() { } public Node(int _val) { val = _val; } public Node(int _val, List<Node> _children) { val = _val; children = _children; } }
public static boolean isBalanced(TreeNode root) { return getHeight(root) != -1; } //返回以该节点为根节点二叉树的深度 private static int getHeight(TreeNode root) { if (root==null)return 0; int left=getHeight(root.left); if (left==-1)return -1; int right=getHeight(root.right); if (right==-1)return -1; if (Math.abs(left-right)>1)return -1; return Math.max(left,right)+1; }
public int findSecondMinimumValue(TreeNode root) { if (root == null || (root.left == null && root.right == null)) return -1;//没有最小节点 //找出候选数,默认就是子节点值,如果子节点值和root值相同,递归,在子树中寻找候选数 int left = root.left.val; int right = root.right.val; if (root.left.val == root.val) left = findSecondMinimumValue(root.left); if (root.right.val == root.val) right = findSecondMinimumValue(root.right); //如果左右候选数都正常,返回较小值就可 if (left != -1 && right != -1) { return Math.min(left, right); } //如果候选数有-1,说明整个子树中没有可供候选的数 if (left != -1) { //左子树正常,答案就是左边的候选数 return left; } else { //右子树正常,返回答案 //或者右子树也没有候选数,返回-1,即right return right; } }
路径总和
路径总和 3-不限起点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int pathnumber; public int pathSum(TreeNode root, int sum) { if (root == null) return 0; Sum(root, sum); pathSum(root.left, sum); pathSum(root.right, sum); return pathnumber; }
public void Sum(TreeNode root, int sum) { if (root == null) return; sum -= root.val; if (sum == 0) { pathnumber++; } Sum(root.left, sum); Sum(root.right, sum); }
public static boolean hasPathSum(TreeNode root, int sum) { if (root == null) return false; if (root.left == null && root.right == null && sum == root.val) { return true; } boolean l = hasPathSum(root.left, sum - root.val); boolean r = hasPathSum(root.right, sum - root.val); return l || r; }
public static List<List<Integer>> pathSum(TreeNode root, int sum) { List<List<Integer>> res = new ArrayList<>(); dfs(root, sum, 0, new ArrayList<>(), res); return res; }
private static void dfs(TreeNode root, int sum, int total, List<Integer> list, List<List<Integer>> res) { if (root == null) return; list.add(root.val); total = total + root.val; if (root.left == null && root.right == null) { if (sum == total) { res.add(new ArrayList<>(list)); } list.remove(list.size() - 1); return; } dfs(root.left, sum, total, list, res); dfs(root.right, sum, total, list, res); list.remove(list.size() - 1); }
public static ListNode reverseKGroup(ListNode head, int k) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode pre = dummy; ListNode end = dummy; while (end.next != null) { for (int i = 0; i < k && end != null; i++) { end = end.next;//分组,end指向小组最后一个节点 } if (end == null) { break;//链表长度小于k,不翻转 } ListNode next = end.next;//下一组起点 end.next = null;//断开 ListNode start = pre.next;//要翻转的头结点
pre.next = reverse(start); start.next = next; pre = start;//要翻转节点的上一个节点 end = start; } return dummy.next; }
环形链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public static ListNode detectCycle(ListNode head) { ListNode fast = head; ListNode slow = head; while (true) { if (fast == null || fast.next == null) return null;//无环 fast = fast.next.next; slow = slow.next; if (fast == slow) break; } //到这里一定有环 fast = head; while (slow != fast) { slow = slow.next; fast = fast.next; } return slow; }
链表相交
1 2 3 4 5 6 7 8 9 10
public static ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) return null; ListNode a = headA; ListNode b = headB; while (a != b) { a = a == null ? headB : a.next; b = b == null ? headA : b.next; } return a; }
public static String addStrings(String num1, String num2) { StringBuilder sb = new StringBuilder(); int c = 0; int i = num1.length() - 1; int j = num2.length() - 1;
while (i >= 0 || j >= 0 || c != 0) { int n1 = i >= 0 ? num1.charAt(i--) - '0' : 0; int n2 = j >= 0 ? num2.charAt(j--) - '0' : 0; int temp = n1 + n2 + c; sb.append(temp % 10); c = temp / 10; } return sb.reverse().toString(); }
数组
哈希表
两数之和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
public static int[] twoSum(int[] nums, int target) { int[] res = new int[2]; if (nums.length == 0) return null; Map<Integer, Integer> map = new HashMap<>(); int temp=0; for (int i = 0; i < nums.length; i++) { temp=target-nums[i]; if (map.containsKey(temp)) { res[1] = i; res[0] = map.get(temp); } map.put(nums[i], i); } return res; }
无重复字符最大子串
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public static int lengthOfLongestSubstring(String s) { int res = 0; Set<Character> set = new HashSet<>(); for (int r = 0, l = 0; r < s.length(); r++) { char c = s.charAt(r); while (set.contains(c)) { set.remove(s.charAt(l)); l++; } set.add(c); res = Math.max(res, r - l + 1); } return res; }
旋转数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public static int[] reverse(int[] nums, int i) { rev(nums, 0, nums.length - 1); rev(nums, 0, i - 1); rev(nums, i, nums.length - 1); return nums; }
public static int[] rev(int[] nums, int start, int end) { int l = start; int r = end; while (r > l) { int temp = nums[l]; nums[l] = nums[r]; nums[r] = temp; r--; l++; } return nums; }
二分法
顺序集合的查找
循环不变量
1,[left,right]
1 2 3 4 5 6 7 8 9 10
while (l<=r){ int mid=l+(r-l)/2; if (nums[mid]>target){ r=mid-1; }else if (nums[mid]<target){ l=mid+1; }else { return mid; } }
2,[left,right)
1 2 3 4 5 6 7 8 9 10
while (l<r){ int mid=l+(r-l)/2; if (nums[mid]>target){ r=mid; }else if (nums[mid]<target){ l=mid+1; }else { return mid; } }
滑动窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public static int[] maxSlidingWindow(int[] nums, int k) { if (nums.length == 0) return new int[0]; int[] res = new int[nums.length - k + 1]; LinkedList<Integer> queue = new LinkedList<>(); for (int i = 0, j = 0; i < nums.length; i++) { if (!queue.isEmpty() && i - queue.peekFirst() >= k) { queue.pollFirst(); } while (!queue.isEmpty() && nums[i] > nums[queue.peekLast()]) { queue.pollLast(); } queue.addLast(i); if (i >= k - 1) { res[j] = nums[queue.peek()]; j++; } } return res; }
public static int lengthOfLongestSubstring(String s) { int res = 0; int l = 0; Map<Character, Integer> map = new HashMap<>(); for (int r = 0; r < s.length(); r++) { if (map.containsKey(s.charAt(r))) { l = Math.max(l, map.get(s.charAt(r))); } res = Math.max(res, r - l + 1); map.put(s.charAt(r), r + 1); } return res; }
public int lengthOfLongestSubstring(String s) { // 记录字符上一次出现的位置 int[] last = new int[128]; for(int i = 0; i < 128; i++) { last[i] = -1; } int n = s.length();
int res = 0; int start = 0; // 窗口开始位置 for(int i = 0; i < n; i++) { int index = s.charAt(i); start = Math.max(start, last[index] + 1); res = Math.max(res, i - start + 1); last[index] = i; } return res; }
public static int fib(int n) { if (n==0)return 0; if (n==1)return 1; int[] dp=new int[n+1]; dp[0]=0; dp[1]=1; for (int i = 2; i <= n; i++) { dp[i]=dp[i-1]+dp[i-2]; } return dp[n]; }
public static int fib2(int n){ if (n==0)return 0; if (n==1)return 1; int dp0=0; int dp1=1; for (int i = 2; i <= n; i++) { int sum=dp0+dp1; dp0=dp1; dp1=sum; } return dp1; }
public static int uniquepaths2(int m, int n) { int[][] dp = new int[m][n]; for (int i = 0; i < m; i++) { dp[i][0] = 1; } for (int i = 0; i < n; i++) { dp[0][i] = 1; } for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } return dp[m - 1][n - 1]; }
//考虑某些位置有障碍 int m=grid.length(); int n=grud[0].length(); //初始化 for (int i = 0; i < m&&grid[i][0]==0; i++) { dp[i][0] = 1; } for (int i = 0; i < n&&grid[0][j]==0; i++) { dp[0][i] = 1; } //遍历-加上判断条件即可 if(grid[i][j]==1)continue;
public static int bag(int bagweight, int[] weight, int[] value) { int[][] dp = new int[weight.length][bagweight + 1]; for (int i = bagweight; i >= weight[0]; i--) { dp[0][i] = dp[0][i - weight[0]] + value[0]; } for (int i = 1; i < weight.length; i++) { for (int j = 0; j <= bagweight; j++) { if (j >= weight[i]) { dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); } } } return dp[weight.length-1][bagweight]; }
public static void main(String[] args) { int[] w = {1, 3, 4}; int[] v = {15, 20, 30}; System.out.println(bag(4, w, v)); }
一维 dp[ ]数组。
遍历背包大小时倒序遍历-为了保证每个物品只用一次。
1 2 3 4 5 6 7 8 9
public static int bag1(int bagweight, int[] weight, int[] value){ int[] dp=new int[bagweight+1]; for (int i = 0; i < weight.length; i++) { for (int j = bagweight; j >= weight[i]; j--) { dp[j]= Math.max(dp[j],dp[j-weight[i]]+value[i]); } } return dp[bagweight]; }
完全背包-每个物品都可以被放入无数次。
只需要改变遍历背包时的遍历顺序。
完全背包
1 2 3 4 5 6 7 8 9
public static int bag2(int bagweight, int[] weight, int[] value) { int[] dp = new int[bagweight + 1]; for (int i = 0; i < weight.length; i++) { for (int j = weight[i]; j <= bagweight; j++) { dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]); } } return dp[bagweight]; }
零钱兑换(1,2,5)
可以先遍历总金额吗?不能。
如果求组合数就是外层 for 循环遍历物品,内层 for 遍历背包。
如果求排列数就是外层 for 遍历背包,内层 for 循环遍历物品
1 2 3 4 5 6 7 8 9 10
public static int coinnum(int[] coins,int money){ int[] dp=new int[money+1]; dp[0]=1; for (int i = 0; i < coins.length; i++) {//遍历物品 for (int j = coins[i]; j <= money; j++) {//遍历容量 dp[j]=dp[j-coins[i]]+dp[j]; } } return dp[money]; }
爬楼梯进阶
每次都可以爬 1,2,3,4,,,,n 步?
等价于完全背包问题。
物品就是一步两步三步。
总量就是总的台阶步数。
1 2 3 4 5 6 7 8 9 10 11 12 13
public static int climb3(int n, int m) { int[] dp = new int[n + 1]; dp[0] = 1; //排列问题-先遍历背包 for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) {//遍历物品 if (i - j >= 0) { dp[i] = dp[i] + dp[i - j]; } } } return dp[n]; }
零钱兑换最少的硬币数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public static int coinmin(int[] coins, int sum) { int[] dp = new int[sum + 1]; Arrays.fill(dp, Integer.MAX_VALUE); dp[0] = 0; for (int i = 0; i < coins.length; i++) { for (int j = coins[i]; j <= sum; j++) { if (dp[j - coins[i]] != Integer.MAX_VALUE) { dp[j] = Math.min(dp[j - coins[i]] + 1, dp[j]); } } } if (dp[sum] == Integer.MAX_VALUE) return -1; return dp[sum]; }
构成完全平方数的最小个数
1 2 3 4 5 6 7 8 9 10 11
public static int sqmin(int n) { int[] dp = new int[n + 1]; Arrays.fill(dp, Integer.MAX_VALUE); dp[0] = 0; for (int i = 0; i <= n; i++) {//遍历背包 for (int j = 1; j * j <= i; j++) {//遍历物品 dp[j] = Math.min(dp[i - j * j] + 1, dp[i]); } } return dp[n]; }
打家劫舍
初级打家劫舍
1 2 3 4 5 6 7 8 9 10 11
public static int rob(int[] nums) { if (nums.length == 0) return 0; if (nums.length == 1) return nums[0]; int[] dp = new int[nums.length]; dp[0] = nums[0]; dp[1] = Math.max(nums[0], nums[1]); for (int i = 2; i < nums.length; i++) { dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]); } return dp[nums.length - 1]; }
环形打家劫舍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public static int rob(int[] nums) { int len=nums.length; if (len==0)return 0; if (len==1)return nums[0]; int res1=helper(nums,0,nums.length-2); int res2=helper(nums,1,nums.length-1); return Math.max(res1,res2); }
private static int helper(int[] nums, int start, int end) { if (start==end)return nums[start]; int[] dp=new int[nums.length]; dp[start]=nums[start]; dp[start+1]=Math.max(nums[start],nums[start+1]); for (int i = start+2; i <= end; i++) { dp[i]= Math.max(dp[i-2]+nums[i],dp[i-1]); } return dp[end]; }
树形打家劫舍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
public static int rob(TreeNode root){ //表示偷某个节点和不偷某个节点的最大值 int[] res=robtree(root); return Math.max(res[0],res[1]); }
private static int[] robtree(TreeNode cur) { if (cur==null)return new int[2]; int[] left = robtree(cur.left); int[] right = robtree(cur.right);
int val1=cur.val+left[0]+right[0]; int val2=Math.max(left[0],left[1])+Math.max(right[0],right[1]); return new int[]{val2,val1}; }
股票问题
买股票最佳时机(只能买卖一次)
1 2 3 4 5 6 7 8 9
public static int maxProfit(int[] prices) { int low=prices[0]; int res=0; for(int i=1;i<prices.length;i++){ low=Math.min(prices[i],low); res=Math.max(res,prices[i]-low); } return res; }
买股票最佳时机(可以买卖多次)
1 2 3 4 5 6 7 8 9
public int maxProfit(int[] prices) { int res=0; for (int i = 1; i < prices.length; i++) { if (prices[i]>prices[i-1]){ res=res+(prices[i]-prices[i-1]); } } return res; }
public static int maxsubarray(int[] nums){ int res=Integer.MIN_VALUE; int count=0; for (int i = 0; i < nums.length; i++) { count=count+nums[i]; if (count>res){ res=count; } if (count<=0)count=0; } return res; }
public static int maxsubarray2(int[] nums){ if (nums.length==0)return 0; int[] dp=new int[nums.length]; dp[0]=nums[0]; int res=nums[0]; for (int i = 1; i < nums.length; i++) { dp[i]= Math.max(dp[i-1]+nums[i],nums[i]); res= Math.max(res,dp[i]); } return res; }
public static int countSubstrings(String s){ int res=0; for (int i = 0; i < s.length(); i++) { res=res+extend(s,i,i,s.length()); res=res+extend(s,i,i+1,s.length()); } return res; }
private static int extend(String s, int i, int j, int length) { int re=0; while (i>=0&&j<length&&s.charAt(i)==s.charAt(j)){ i++; j--; re++; } return re; } public static int huiwen(String s){ boolean[][] dp=new boolean[s.length()][s.length()]; int res=0; for (int i = s.length()-1; i >=0; i--) { for (int j = i; j < s.length(); j++) { if (s.charAt(i)==s.charAt(j)){ if (j-i<=1){ res++; dp[i][j]=true; }else if(dp[i+1][j-1]){ res++; dp[i][j]=true; } } } } return res; } //最长回文子串 public static String maxhuiwen(String s){ if (s.length()<2)return s; int start=0; int max=1; int len=s.length(); for (int i = 0; i < len; ) { //剩下的已经不可能更长了。 if (len-i<=max/2)break; int l=i; int r=i; while (r<len-1&&s.charAt(r)==s.charAt(r+1)){ r++; } i=r+1; while (r<len-1&&l>0&&s.charAt(r+1)==s.charAt(l-1)){ r++; l--; } if (r-l+1>max){ max=r-l+1; start=l; } } return s.substring(start,start+max); }
最长回文子序列
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public static int longestPalindromeSubseq(String s) { int[][] dp = new int[s.length()][s.length()]; for (int i = s.length() - 1; i >= 0; i--) { dp[i][i] = 1; for (int j = i + 1; j < s.length(); j++) { if (s.charAt(i) == s.charAt(j)) { dp[i][j] = dp[i + 1][j - 1] + 2; } else { dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); } } } return dp[0][s.length() - 1]; }
判断子序列
1 2 3 4 5 6 7 8 9 10 11
public static boolean isSubsequence(String s, String t) { if (s.length() == 0) return true; int ss = 0; for (int i = 0; i < t.length(); i++) { if (s.charAt(ss) == t.charAt(i)) { ss++; if (ss == s.length()) return true; } } return false; }
public class LRUCache { private class node { //双向链表类 int val; int key; node pre; node next; public node(int key, int val) { this.val = val; this.key = key; } }
public static int trap(int[] height) { int len = height.length; int[] maxl = new int[len]; int[] maxr = new int[len]; int res = 0; for (int i = 1; i < len; i++) { maxl[i] = Math.max(maxl[i - 1], height[i - 1]); } for (int i = len - 2; i >= 0; i--) { maxr[i] = Math.max(maxr[i + 1], height[i + 1]); }
for (int i = 0; i < len; i++) { int h = Math.min(maxl[i], maxr[i]); if (h > height[i]) { res = res + h - height[i]; } } return res; }
单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public class Singleton { private volatile static Singleton uniqueInstance; private Singleton(){
} public static Singleton getUniqueInstance(){ if (uniqueInstance==null){ synchronized (Singleton.class){ if (uniqueInstance==null){ uniqueInstance=new Singleton(); } } } return uniqueInstance; } }
public static int findKthLargest(int[] nums, int k) { int len = nums.length; PriorityQueue<Integer> minheap = new PriorityQueue<>(len, (a, b) -> a - b);//默认最小堆 for (int i = 0; i < len; i++) { minheap.add(nums[i]); } for (int i = 0; i < len - k; i++) { minheap.poll(); } return minheap.peek(); }
public int findKthLargest2(int[] nums, int k) { int len = nums.length; // 最小堆 PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(k + 1, (a, b) -> (a - b)); for (int num : nums) { priorityQueue.add(num); if (priorityQueue.size() == k + 1) { priorityQueue.poll(); } } return priorityQueue.peek(); }
杨辉三角
1 2 3 4 5 6 7 8 9 10 11
public List<Integer> getRow(int rowIndex) { List<Integer> list = new ArrayList<>(); while (rowIndex >= 0) { rowIndex--; list.add(1); for (int i = list.size() - 2; i > 0; i--) { list.set(i, list.get(i) + list.get(i - 1)); } } return list; }
public static int firstMissingPositive(int[] nums) { Set<Integer> set=new HashSet<>(); for (int i = 0; i < nums.length; i++) { set.add(nums[i]); } for (int i = 1; i <= nums.length; i++) { if (!set.contains(i)){ return i; } } return nums.length+1; } public static int firstMissingPositive2(int[] nums) { int len=nums.length; for (int i = 0; i < len; i++) { if (nums[i]<=0)nums[i]=len+1; } for (int i = 0; i < len; i++) { int num= Math.abs(nums[i]); if (num<=len){ nums[num-1]=-Math.abs(nums[num-1]); } } for (int i = 0; i < len; i++) { if (nums[i]>0){ return i+1; } } return len+1; }