day07-算法热题10题

LeetCode 热题 Hot 100

暂时不写

class Trie {

        class TrieNode {
            // 是否是完整的单词
            boolean isWord;
            // 子
            TrieNode[] children;

            public TrieNode() {
                isWord = false;
                this.children = new TrieNode[26];
            }
        }

        TrieNode root;

        public Trie() {
            root = new TrieNode();
        }

        public void insert(String word) {
            TrieNode cur = root;
            for (int i = 0; i < word.toCharArray().length; i++) {
                char c = word.charAt(i);
                // 26个字符的长度
                if (cur.children[c - 'a'] == null) {
                    TrieNode child = new TrieNode();
                    cur.children[c - 'a'] = child;
                }
                cur = cur.children[c - 'a'];
            }
            cur.isWord = true;
        }

        public boolean search(String word) {
            TrieNode cur = root;
            for (int i = 0; i < word.toCharArray().length; i++) {
                char c = word.charAt(i);
                if (cur.children[c - 'a'] == null) {
                    return false;
                }
                cur = cur.children[c - 'a'];
            }
            return cur.isWord;
        }

        public boolean startsWith(String prefix) {
            TrieNode cur = root;
            for (int i = 0; i < prefix.toCharArray().length; i++) {
                char c = prefix.charAt(i);
                if (cur.children[c - 'a'] == null) {
                    return false;
                }
                cur = cur.children[c - 'a'];
            }
            return true;
        }
    }

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */

class Solution {
      /**
     * 最小堆
     * 返回最后堆顶元素
     */
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        for (int num : nums) {
            minHeap.add(num);
            // 当发现最小堆的容量大于k,就把最小的那个移除
            if (minHeap.size() > k) {
                minHeap.remove();
            }
        }
        return minHeap.peek();
    }
}
class Solution {
 /**
     * dp[i][j]表示以第i行第j列为右下角所能构成的最大正方形边长, 则递推式为:
     * dp[i][j] = 1 + min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]);
     **/
    public int maximalSquare(char[][] matrix) {
        int m = matrix.length;
        if (m < 1) return 0;
        int n = matrix[0].length;
        int[][] dp = new int[m + 1][n + 1];
        int max = 0;
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (matrix[i - 1][j - 1] == '1') {
                    dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1]));
                    max = Math.max(max, dp[i][j]);
                }
            }
        }
        return max * max;
    }
}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    /**
     * 其实就是把二叉树上的每个节点的左右子节点都交换一下
     * 右翻右 左翻左
     * 右变左 左变右
     */
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return null;
        TreeNode right = invertTree(root.right);
        TreeNode left = invertTree(root.left);
        root.right = left;
        root.left = right;
        return root;
    }
}


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    /*
 public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) return true;
        ListNode pre = null, cur = head;
        while (cur.next != null) {
            pre = cur;
            cur = cur.next;
        }
        if (cur.val != head.val) {
            return false;
        }
        // 把两个数字单独拎出来比较
        // 1->2->2->1

        // 拎出来 2->2
        ListNode next = head.next;
        head.next = null;
        // 把最后一个踢出
        pre.next = null;

        return isPalindrome(next);

    }*/

    /*
    public boolean isPalindrome(ListNode head) {
        List<Integer> list = new ArrayList<>();
        ListNode cur = head;
        while (cur != null) {
            list.add(cur.val);
            cur = cur.next;
        }
        int start = 0, end = list.size() - 1;
        while (start <= end) {
            if (!list.get(start).equals(list.get(end))) {
                return false;
            } else {
                start++;
                end--;
            }
        }
        return true;
    }*/

     /**
     * 快慢指针法
     * 1、先通过 双指针技巧 中的快慢指针来找到链表的中点
     * 2、如果 fast 指针没有指向 null,说明链表长度为奇数,slow 还要再前进一步
     * 3、从 slow 开始反转后面的链表,现在就可以开始比较回文串了
     */
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) return true;
        ListNode fast = head, slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        if (fast != null) {
            slow = slow.next;
        }
        ListNode left = head;
        ListNode right = reverse(slow);
        while (right != null) {
            if (left.val != right.val)
                return false;
            left = left.next;
            right = right.next;
        }
        return true;
    }

    ListNode reverse(ListNode head) {
        ListNode pre = null, cur = head;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
}
      public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return root;

        TreeNode pqInLeft = lowestCommonAncestor(root.left, p, q);
        TreeNode pqInRight = lowestCommonAncestor(root.right, p, q);

        // 一定在右边
        if (pqInLeft == null) return pqInRight;

        // 一定在左边
        if (pqInRight == null) return pqInLeft;
        
        return root;
    }

class Solution {
      public int[] productExceptSelf(int[] nums) {
        int[] dp = new int[nums.length];
        int l = 1, r = 1;
        //         a    b     c      d
        //        bcd  acd   abd    abc
        //         1   1*a   a*b    ab*c
        // l=1
        // r=1         adc   ab*d    abc*1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = l;
            l *= nums[i];
        }
        for (int i = nums.length - 1; i >= 0; i--) {
            dp[i] *= r;
            r *= nums[i];
        }
        return dp;
    }
}
暂时不写
class Solution {
     public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length;
        int n = matrix[0].length;
        int start = 0, end = m * n - 1;
        while (start <= end) {
            int mid = start + ((end - start) >>> 1);
            // 5 /4 = 1
            int x = mid / n;
            // 5 % 4 =1
            int y = mid % n;
            if (target == matrix[x][y]) return true;
            else if (target > matrix[x][y]) {
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }
        return false;
    }
}
class Solution {
     /**
     * 二分查找
     * 从右上角看是二叉搜索树
     */
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length;
        int n = matrix[0].length;
        int i = 0, j = n - 1;
        while (i <= m - 1 && j >= 0) {
            if (target < matrix[i][j]) {
                // 往左边移动
                j--;
            } else if (target > matrix[i][j]) {
                i++;
            } else {
                return true;
            }
        }
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫吹过的柚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值