• 算法


    寻找逆序对(归并思想)
    public int InversePairs(int [] array) {
        if(array == null || array.length == 0) return 0;
        int i = 0;
        int j = array.length - 1;
        int[] copy = new int[array.length];
        return countPairs(array,copy,i,j);
    }
    
    public int countPairs(int[] array,int[] copy,int left,int right){
        if(left >= right) return 0;
        int res = 0;
        int mid = left + (right - left) / 2;
        int leftNum = countPairs(array,copy,left,mid) % 1000000007;
        int rightNum = countPairs(array,copy,mid + 1,right) % 1000000007;
        int i = left;
        int j = mid;
        int m = mid + 1;
        int n = right;
        int k = right;
        while(j >= i && n >= m){
            if(array[j] > array[n]){
                res += (n - mid); // core code
                if(res > 1000000007) res %= 1000000007;
                copy[k--] = array[j--];
            }
            else copy[k--] = array[n--];
        }
        while(j >= i){
            copy[k--] = array[j--];
        }
        while(n >= m){
            copy[k--] = array[n--];
        }
        for(int p = left; p <= right; p++){
            array[p] = copy[p];
        }
        return (res + leftNum + rightNum) % 1000000007;
    }
    
    寻找波峰(只有一个波峰)----二分思想
    public int findPeakElement(int[] nums) {
        if(nums == null || nums.length == 0) return 0;
        int i = 0;
        int j = nums.length -1;
        while(i <= j){
            int m = i + (j - i) / 2; 
    		//注意此处的越界
            int target = (m + 1 == nums.length) ? Integer.MIN_VALUE : nums[m + 1];
            if(nums[m] < target) i = m + 1;
            else j = m - 1;
        }
        return i;
    }
    
    循环数组求最小值(无重复)----二分思想
    public int findMin(int[] nums) {
        if(nums == null || nums.length == 0) return 0;
        int right = nums.length - 1;
        int i = 0;
        int j = nums.length - 1;
        while(i <= j){
            int m = i + (j - i) / 2;
            if(nums[m] > nums[right]) i = m + 1; //core code
            else j = m - 1;
        }
        return nums[i];
    }
    
    循环数组求最小值(有重复)----二分思想
    public int findMin(int[] nums) {
        if(nums == null || nums.length == 0) return 0;
        int i = 0;
        int j = nums.length - 1;
        while(nums[i] >= nums[j]){
            if(j - i == 1){
                return nums[j];
            }
            else{
                int m = i + (j - i) / 2;
                if(nums[i] == nums[m] && nums[j] == nums[m]){
                    return getMin(nums,i,j);
                }
    			//core code
                else if(nums[m] > nums[j]) i = m + 1;
                else j = m; 
            }
        }
        return nums[i];
    }
    
    public int getMin(int[] nums,int i,int j){
        int res = Integer.MAX_VALUE;
        while(i <= j){
            res = Math.min(res,nums[i]);
            i++;
        }
        return res;
    }
    
    循环数组查找(无重复)----二分思想
    public int search(int[] nums, int target) {
        if(nums == null || nums.length == 0) return -1;
        int i = 0;
        int j = nums.length - 1;
        while(i <= j){
            int m = i + (j - i) / 2;
            if(nums[m] == target) return m;
            if(nums[m] >= nums[i]){
                if(target >= nums[i] && target < nums[m]) j = m - 1;
                else i = m + 1;
            }
            else{
                if(target > nums[m] && target <= nums[j]) i = m + 1;
                else j = m - 1;
            }
        }
        return -1;
    }
    
    循环数组查找(有重复)----二分思想
    public boolean search(int[] nums, int target) {
        if(nums == null || nums.length == 0) return false;
        int i = 0;
        int j = nums.length - 1;
        while(i <= j){
            int m = i + (j - i) / 2;
            if(nums[m] == target) return true;
            if(nums[m] > nums[i]){
                if(target >= nums[i] && target < nums[m]) j = m - 1;
                else i = m + 1;
            }
            else if(nums[m] < nums[i]){
                if(target > nums[m] && target < nums[j]) i = m + 1;
                else j = m - 1;
            }
            else{
                i = i + 1;
            }
        }
        return false;
    }
    
    计算subtree的val和----后序迭代思想(Most Frequent Subtree Sum)
    HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
    int maxCount = 0;
    public int[] findFrequentTreeSum(TreeNode root) {
        if(root == null) return new int[0];
        List<Integer> res = new ArrayList<Integer>();
        postOrder(root,map);
        for(Integer i : map.keySet()){
            if(map.get(i) == maxCount) res.add(i);
        }
        int[] ans = new int[res.size()];
        for(int i = 0; i < res.size(); i++){
            ans[i] = res.get(i);
        }
        return ans;
    }
    
    public int postOrder(TreeNode root,HashMap<Integer,Integer> map){
        if(root == null) return 0;
        int left = postOrder(root.left,map);
        int right = postOrder(root.right,map);
        int sum = root.val + left + right;
        int count = map.getOrDefault(sum,0) + 1;
        map.put(sum,count);
        maxCount = Math.max(maxCount,count);
        return sum;
    }
    
    树的遍历(非递归)

    后序

    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null) return res;
        Stack<TreeNode> s = new Stack<>();
        s.push(root);
        TreeNode pre = null;
        while(!s.isEmpty()){
            TreeNode node = s.peek();
            if((node.left == null && node.right == null) || (pre != null && (node.left == pre || node.right == pre))){
                res.add(node.val);
                pre = node;
                s.pop();
            }
            else{
                if(node.right != null) s.push(node.right);
                if(node.left != null) s.push(node.left);
            }
        }
        return res;
    }
    

    前序

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        Stack<TreeNode> s = new Stack<>();
        if(root == null) return res;
        while(!s.isEmpty() || root != null){
            s.push(root);
            res.add(root.val);
            root = root.left;
            while(!s.isEmpty() && root == null){
                root = s.pop().right;
            }
        }
        return res;
    }
    

    中序

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        Stack<TreeNode> s = new Stack<>();
        if(root == null) return res;
        while(!s.isEmpty() || root != null){
            s.push(root);
            root = root.left;
            while(!s.isEmpty() && root == null){
                root = s.pop();
                res.add(root.val);
                root = root.right;
            }
        }
        return res;
    }
    
    最大路径和----后序迭代思想(Binary Tree Maximum Path Sum)
    public int maxValue;
    public int maxPathSum(TreeNode root) {
        maxValue = Integer.MIN_VALUE;
        maxPathDown(root);
        return maxValue;
    }
    
    public int maxPathDown(TreeNode root){
        if(root == null) return 0;
        int left = Math.max(0,maxPathDown(root.left));
        int right = Math.max(0,maxPathDown(root.right));
        maxValue = Math.max(maxValue,left + right + root.val);
        return Math.max(left,right) + root.val;
    }
    
    BST转双向链表
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null) return null;
        TreeNode pre = null;
        TreeNode root = null;
        boolean f = true;
        Stack<TreeNode> s = new Stack<>();
        while(!s.isEmpty() || pRootOfTree != null){
            s.push(pRootOfTree);
            pRootOfTree = pRootOfTree.left;
            while(!s.isEmpty() && pRootOfTree == null){
                pRootOfTree = s.pop();
                if(f){                    
                    pre = pRootOfTree; 
                    root = pRootOfTree;
                    f = false;
                }
                else{
                    pRootOfTree.left = pre;
                    pre.right = pRootOfTree;
                    pre = pRootOfTree;
                }
                pRootOfTree = pRootOfTree.right;
            }
        }
        return root;
    }
    
    最长无重复字符串----双指针(Longest Substring Without Repeating Characters)
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.isEmpty()) return 0;
        HashMap<Character,Integer> map = new HashMap<Character,Integer>();
        //i表示字符串终点,j表示下次查找的起点,只会越来越大
        int j = 0;
        int max = 0;
        for(int i = 0; i < s.length(); i++){
            if(map.containsKey(s.charAt(i))){
                j = Math.max(j,map.get(s.charAt(i)) + 1);
            }
            map.put(s.charAt(i),i);
            max = Math.max(max,i - j + 1);
        }
        return max;
    }
    
    最长公共子序列----dp
    public static String LCS(String str,String ptr){
        StringBuffer s = new StringBuffer();
        int[][] dp = new int[str.length() + 1][ptr.length() + 1];
        for(int i = 1; i < dp.length; i++){
            for(int j = 1; j < dp[0].length; j++){
                if(str.charAt(i - 1) == ptr.charAt(j - 1)){
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }
                else{
                    dp[i][j] = Math.max(dp[i - 1][j],dp[i][ j - 1]);
                }
            }
        }
    
        int i = str.length();
        int j = ptr.length();
        while(i > 0 && j > 0){
            if(str.charAt(i - 1) == ptr.charAt(j - 1)){
                s = s.append(str.charAt(i - 1));
                i--;
                j--;
            }
            else{
                if(dp[i][j - 1] > dp[i - 1][j]) j--;
                else i--;
            }
        }
        return s.reverse().toString();
    }
    
    最长公共子串----dp
    public static String LCS(String str,String ptr){
        StringBuffer s = new StringBuffer();
        int maxLen = Integer.MIN_VALUE;
        int row = 0;
        int col = 0;
        int[][] dp = new int[str.length()][ptr.length()];
        for(int i = 0; i < dp.length; i++){
            for(int j = 0; j < dp[0].length; j++){
                if(str.charAt(i) == ptr.charAt(j)){
                    if(i == 0 || j == 0) dp[i][j] = 1;
                    else dp[i][j] = dp[i - 1][j - 1] + 1;
                    if(dp[i][j] > maxLen){
                        maxLen = dp[i][j];
                        row = i;
                        col = j;
                    }
                }
            }
        }
    
        while(row >= 0 && col >= 0 && maxLen > 0){
            s = s.append(str.charAt(row));
            row--;
            col--;
            maxLen--;
        }
        return s.reverse().toString();
    }
  • 相关阅读:
    postgresql小纪
    Java的大内存分页支持
    GCViewer / MAT
    js给数组去重写法
    解决mybatis foreach 错误: Parameter '__frch_item_0' not found
    JSON字符串和JS对象之间的转换
    使用IntelliJ IDEA搭建多maven模块JAVA项目
    jstl中的sql:query标签获取的结果如何格式化输出
    Label控件如何根据字符串自定义大小
    winform/窗体鼠标事件编程中的几个问题
  • 原文地址:https://www.cnblogs.com/LeonNew/p/6622779.html
Copyright © 2020-2023  润新知