Daily LeetCode – day0036 0646. Maximum Length of Pair Chain

// 0646. Maximum Length of Pair Chain
class Solution {
    public int findLongestChain(int[][] pairs) {
        PriorityQueue<Pair> pairPriorityQueue = new PriorityQueue<>((Pair p1, Pair p2) -> p1.right - p2.right);
        for (int[] pair : pairs) {
            pairPriorityQueue.offer(new Pair(pair[0], pair[1]));
        }
        int ans = 0;
        int currentRight = Integer.MIN_VALUE;
        while (!pairPriorityQueue.isEmpty()) {
            if (pairPriorityQueue.peek().left > currentRight) {
                ++ans;
                currentRight = pairPriorityQueue.peek().right;
            }
            pairPriorityQueue.poll();
        }
        return ans;
    }
}

class Pair {
    int left;
    int right;

    Pair(int left, int right) {
        this.left = left;
        this.right = right;
    }
}
学习笔记:
这是一道中等难度的题目,就是贪心算法看电影的类似题目。
这道题可以用排序来做,但是跑出来9ms。
然后我用了优先队列,就可以跑出8ms。
这道题其实我再08.19就做了,然后这次抽到后,我就尝试使用了新学到的TreeSet来做,但发现里面有些数组是重复的,我就用了特殊手段处理,重写了比较方法,让返回值永远不为0,就避免了重复放不进去的尴尬。
发表在 每日LeetCode | 留下评论

Ukulele谱《给你一瓶魔法药水》告五人

发表在 樊轶群Ukulele谱 | 留下评论

Daily LeetCode – day0035 0687. Longest Univalue Path

// 0687. Longest Univalue Path
class Solution {
    public int longestUnivaluePath(TreeNode root) {
        int[] ans = new int[]{0};
        if (root == null) return 0;
        dfs(root, ans);
        return ans[0];
    }

    int dfs(TreeNode root, int[] ans) {
        if (root.left == null && root.right == null) return 1;
        int left = 0;
        int right = 0;
        if (root.left != null) {
            left = dfs(root.left, ans);
            if (root.left.val != root.val) left = 0;
        }
        if (root.right != null) {
            right = dfs(root.right, ans);
            if (root.right.val != root.val) right = 0;
        }
        int selfMax = left + right;
        if (selfMax > ans[0]) ans[0] = selfMax;
        if (left > right) return left + 1;
        return right + 1;
    }
}
学习笔记:
今天这道题目之前教学过,这道二叉树题有点像动态规划,需要从下往上状态转移,但由于存储方式是二叉树,所以还是应该用回溯算法,不断递归下去回溯上来。
发表在 每日LeetCode | 留下评论

Daily LeetCode – day0034 1475. Final Prices With a Special Discount in a Shop

// 1475. Final Prices With a Special Discount in a Shop
class Solution {
    public int[] finalPrices(int[] prices) {
        int len = prices.length;
        for (int i = 0; i < len; ++i) {
            for (int j = i + 1; j < len; ++j) {
                if (prices[i] >= prices[j]) {
                    prices[i] = prices[i] - prices[j];
                    break;
                }
            }
        }
        return prices;
    }
}
学习笔记:
9月第1天,果然是一道简单题。数组题。
一开始手写了单调栈来做,但是连续两个相等的数字不太好操作就放弃了,还是双重循环最简单了。
发表在 每日LeetCode | 留下评论

Daily LeetCode – day0033 0946. Validate Stack Sequences

// 0946. Validate Stack Sequences
class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        int len = pushed.length;
        boolean[] pop = new boolean[len];
        int i = 0;
        int j = 0;
        while (j < len) {
            if (pushed[i] == popped[j]) {
                pop[i] = true;
                ++j;
                if (j == len) return true;
                while (pop[i]) {
                    --i;
                    if (i < 0) {
                        ++i;
                        while (pop[i]) {
                            ++i;
                        }
                    }
                }
            } else {
                ++i;
                if (i == len) return false;
                while (pop[i]) {
                    ++i;
                    if (i == len) return false;
                }
            }
        }
        return true;
    }
}
学习笔记:
这是一道栈的模拟算法问题,我一开始用了栈,花了11ms。
后来在原本数组上面操作,但是发现还是有问题,数据会丢失维度,后来多建一个数组记录pushed数组中的元素是否有使用过,本来我觉得这样写得更复杂了,空间会省,但可能更慢,结果就1ms跑完了。
今天也是8月最后1天,完成了8月每日1题全部打卡挑战,完美。
发表在 每日LeetCode | 留下评论

Daily LeetCode – day0032 0998. Maximum Binary Tree II

// 0998. Maximum Binary Tree II
class Solution {
    public TreeNode insertIntoMaxTree(TreeNode root, int val) {
        if (val > root.val) {
            return new TreeNode(val, root, null);
        }
        TreeNode up = root;
        TreeNode down = root.right;
        while (down != null && val < down.val) {
            up = down;
            down = down.right;
        }
        up.right = new TreeNode(val, down, null);
        return root;
    }
}
学习笔记:
这道题是Daily LeetCode – day0022 0654. Maximum Binary Tree的姊妹体。
本来把二叉树还原成数组,然后再把val添加后的数组变成二叉树。
但是最佳答案是就观察最右边的一些节点,找合适位置插入。最终0ms解决。
发表在 每日LeetCode | 留下评论

Daily LeetCode – day0031 1470. Shuffle the Array

// 1470. Shuffle the Array
class Solution {
    public int[] shuffle(int[] nums, int n) {
        int[] ans = new int[n * 2];
        for (int i = 0; i < n; ++i) {
            ans[i * 2] = nums[i];
            ans[i * 2 + 1] = nums[n + i];
        }
        return ans;
    }
}
学习笔记:
今天是数组的一道水题,就是找规律。
发表在 每日LeetCode | 留下评论

Daily LeetCode – day0030 0793. Preimage Size of Factorial Zeroes Function

// 0793. Preimage Size of Factorial Zeroes Function
class Solution {
    public int preimageSizeFZF(int k) {
        long left = 0;
        long right = k * 5L;
        long middle;
        while (left < right) {
            middle = (left + right) / 2;
            int zeroes = trailingZeroes(middle);
            if (zeroes > k) {
                right = middle - 1;
            } else if (zeroes < k) {
                left = middle + 1;
            } else {
                left = middle;
                right = middle;
            }
        }
        if (trailingZeroes(left) == k) return 5;
        return 0;
    }

    private int trailingZeroes(long n) {
        int ans = 0;
        while (n != 0) {
            n /= 5;
            ans += n;
        }
        return ans;
    }
}
学习笔记:
这道题用到了很多数学的内容,还有二分法内容。
这道题的基础先是0172. Factorial Trailing Zeroes这道中等题。
2因素肯定比5多,所以最后几个0得看有几个5参与运算了。
5,10,15,20这都还是1个5参与,但25,50,75,100可就有2个5了,125,250,375,500那就有3个5了。规律其实就是把那个数字除以5看一下还剩多少,加上去,再除以5看一下剩多少,一直除到0为止。
比如130的阶乘,
先除以5得26,答案先是26,代表有26个单个5参与了。(5,10,15,20……)
再除以5得5,答案先是31,代表有5个双个5参与了。(25,50,75,100,125)
再除以5得1,答案是32,代表有1个三个5参与了。(125)
就是这样层层计算可以得出130阶层最后有32个5参与运算,也就有32个零在最后。

接下来,回到本题!
我们要用二分法处理这道题目,left是0,这个很好理解,right是多少呢?直接写2147482647会超时的,所以得有合适的范围。
我们知道:
要有一个5参与运算,至少是5的阶乘,
要有两个5参与运算,至少是10的阶乘,
要有五个5参与运算,至少是25的阶乘,
但是要有六个5参与运算,还是至少是25的阶乘,因为25里有两个5。
要有十二个5参与运算,至少是50的阶乘。
所以这个至少几的阶乘,一定是会小于5的数量的五倍的。
这一点我很难想通,但是现在起码想通了,如果再想不通得看上面这段例举了。
因此右边界就确定是k*5了,但这道题最后一个样例坑爹了是1000000000,乘完会越界然后结果就不对了,这个得需要用到long。
我在二分法求出结果后做的校验方案就是如果那这个left去求解,刚好是k,那么说明存在,也就是会有5个数字,可能是01234结尾也可能是56789结尾。
但如果不等于k,那说明不存在,也就是一下子阶乘计算中乘了一个带有多个5的数字。

真是一道特别绕的题目,虽然只是小学数学,但数学思路不太好的笨蛋绕到死也会解不开的吧。
发表在 每日LeetCode | 2条评论

Daily LeetCode – day0029 0662. Maximum Width of Binary Tree

// 0662. Maximum Width of Binary Tree
class Solution {
    public int widthOfBinaryTree(TreeNode root) {
        Queue<Pair> queue = new LinkedList<>();
        queue.offer(new Pair(root, 0L));
        long maxWidth = 1L;
        while (!queue.isEmpty()) {
            int queueSize = queue.size();
            long left = 0L;
            long right = 0L;
            for (int i = 0; i < queueSize; ++i) {
                Pair pair = queue.poll();
                TreeNode node = pair.node;
                long index = pair.index;
                if (i == 0) left = index;
                right = index;
                if (node.left != null) {
                    queue.offer(new Pair(node.left, (index << 1) + 1));
                }
                if (node.right != null) {
                    queue.offer(new Pair(node.right, (index << 1) + 2));
                }
            }
            if (right - left + 1 > maxWidth) {
                maxWidth = right - left + 1;
            }
        }
        return (int) maxWidth;
    }
}

class Pair {
    TreeNode node;
    long index;

    public Pair(TreeNode node, Long index) {
        this.node = node;
        this.index = index;
    }
}
学习笔记:
这是一道二叉树的题目,我使用了宽度优先搜索。
一开始的写法我用了宽度优先搜索,把null的结点也都全部塞进去一起遍历了,这样做的后果就是超时了……
然后我就尝试把结点的下标也都放进去一起,这样就不需要空节点了,但是怎么捆绑呢,想到了用C++的Pair,但是java的Pair是在外置的模块里面,放进去一跑编译都通不过。
实在无奈,就手写了一个Pair类,1ms跑完,超过99.9%还是比较满意的。
这里用了一个日常小技巧,乘以2写成左移1位。
发表在 每日LeetCode | 留下评论

Daily LeetCode – day0028 1464. Maximum Product of Two Elements in an Array

// 1464. Maximum Product of Two Elements in an Array
class Solution {
    public int maxProduct(int[] nums) {
        int first = 0;
        int second = 0;
        for (int num : nums) {
            if (num > first) {
                second = first;
                first = num;
            } else if (num > second) {
                second = num;
            }
        }
        return (first - 1) * (second - 1);
    }
}
学习笔记:
今天又是一道数组的入门题,就只需要维护两个变量即可。
发表在 每日LeetCode | 留下评论