TommyCpp / AhaMoment

Note, Practice project, leetcode and other stuff.
1 stars 3 forks source link

Daily check in #3

Open TommyCpp opened 6 years ago

TommyCpp commented 6 years ago

496. Next Greater Element I

https://leetcode.com/problems/next-greater-element-i/description/ 维护一个Map用于存储每个字母对应的结果

TommyCpp commented 6 years ago

349. Intersection of Two Arrays

https://leetcode.com/problems/intersection-of-two-arrays/description/ 使用Python中的字典key作为set(因为似乎不能直接使用set

TommyCpp commented 6 years ago

783. Minimum Distance Between BST Nodes

https://leetcode.com/problems/minimum-distance-between-bst-nodes/description/ BST的中序遍历基本步骤 定义一个递归函数dfs

void dfs(TreeNode root) {
        if (root == null) return;
        dfs(root.left); 
        if (prev != null)
            result = Math.min(result, root.val - prev);  // prev  and result is variable subject to class
        prev = root.val;
        dfs(root.right);
    }
TommyCpp commented 6 years ago

404. Sum of Left Leaves

https://leetcode.com/problems/sum-of-left-leaves/description/ 此题的关键是对于左子树和右子树有不同的迭代策略,所以要有两个迭代函数

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if (null == root) {
            return 0;
        }
        return this.sumOfLeftLeaves(root.left, true) + this.sumOfLeftLeaves(root.right, false);
    }

    private int sumOfLeftLeaves(TreeNode root, boolean isLeft) {
        if (null == root) {
            return 0;
        }
        if (root.left == null && root.right == null) { //找出所有叶子节点,通过函数的isLeft判断是不是左叶子
            return isLeft ? root.val : 0;
        }
        return this.sumOfLeftLeaves(root.left, true) + this.sumOfLeftLeaves(root.right, false);
    }
}
TommyCpp commented 6 years ago

538. Convert BST to Greater Tree

https://leetcode.com/problems/convert-bst-to-greater-tree/description/ 中序遍历,同时累计BST树中的所有数之和

TommyCpp commented 6 years ago

371. Sum of Two Integers

https://leetcode.com/problems/sum-of-two-integers/description/

class Solution {
    public int getSum(int a, int b) {
        if(b == 0){//当进位被消耗完的时候退出
            return a;
        }
        int next = a & b; //当且仅当a,b都是1的时候才进一位
        next <<= 1; //进一位
        a  = a ^ b; //当且进当a,b中一个0一个1的时候才出现1
        return getSum(a,next); //
    }
}
TommyCpp commented 6 years ago

387. First Unique Character in a String

https://leetcode.com/problems/first-unique-character-in-a-string/description/ 除了使用counter API之外,还可以使用str的count函数

class Solution:
    def firstUniqChar(self, s):
        """
        :type s: str
        :rtype: int
        """
        letters = "abcdefghijklmnopqrstuvwxyz"
        unique = [s.index(l) for l in letters if s.count(l) == 1] 
        return -1 if len(unique) == 0 else min(unique)
TommyCpp commented 6 years ago

789. Escape The Ghosts

https://leetcode.com/problems/escape-the-ghosts/description/ 题目的关键是理解 只要有Ghost能够在你之前到达Target,你就一定会失败 因此只要对比Target到原点距离和Ghost到Target之间距离即可

TommyCpp commented 6 years ago

712. Minimum ASCII Delete Sum for Two Strings

https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/description/

动态规划问题

我们使用a1,a2表示当前s1, s2的子串,最终目标是使得a1 == a2并且删除的字符ASCII值最小

1. 定义子问题:

dp[i][j]表示针对s1[:i],s2[:j]的答案

2. 初始状态

3. 转移方程

TommyCpp commented 6 years ago

860. Lemonade Change

https://leetcode.com/problems/lemonade-change/description/ 注意在该场景中,针对20的情况有两种不同的找钱方案:

  1. 找$10+$5
  2. 3张$5
TommyCpp commented 6 years ago

653. Two Sum IV - Input is a BST

https://leetcode.com/problems/two-sum-iv-input-is-a-bst/description/

创建一个数组values用于记录BST中节点的值, 递归的扫描节点,如果k-root.val,即当前值与目标值的差值在values里面,则返回True 否则,values记录当前节点,继续搜索

但是此处没有利用BST中左右子树值的确定关系

TommyCpp commented 6 years ago

696. Count Binary Substrings

https://leetcode.com/problems/count-binary-substrings/description/

设置两个标记cur, last 从第2个字符开始遍历字符串s 当字符i与字符i-1不同的时候,我们可以判定此处发生了0/1转变,例如0010,当i=2的时候发生转变,此时cur=2last=0 我们将cur的值赋给last,同时将cur重新设定为1 然后进行一个判断last >= cur是否为true

TommyCpp commented 6 years ago

841. Keys and Rooms

https://leetcode.com/problems/keys-and-rooms/description/

使用一个opened数组来记录各个房间是否打开过 依次打开所有没有打开过的房间,如果房间里的钥匙可以打开尚未打开的房间,则继续 否则返回, 判断此时是否所有房间都打开过

本质上来说,这是一个图遍历问题,钥匙对应图的邻居

TommyCpp commented 6 years ago

477. Total Hamming Distance

https://leetcode.com/problems/total-hamming-distance/description/

TommyCpp commented 6 years ago

563. Binary Tree Tilt

https://leetcode.com/problems/binary-tree-tilt/description/

首先构造一个SumTree用于记录每个节点所有子节点的和,然后再计算每个节点的tilt

TommyCpp commented 6 years ago

167. Two Sum II - Input array is sorted

https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/ 注意给出的数组的特殊性质:排序数组 考虑从头尾设置两个指针,分别指向最大值和最小值 由于题目保证有且仅有一个解,所以通过调整头尾两个指针的位置一定能够得到结果

如果两个指针相加值小于target,则我们需要减小两个指正相加的值,因此,将尾指针向前移动 如果两个指针相加值大于target,则我们需要减小两个指正相加的值,因此,将头指针向后移动

可以不设置循环跳出条件(即可以设置为while(true)),然后在循环中等到头尾指针相加等于target的时候break即可

TommyCpp commented 6 years ago

2. Add Two Numbers

https://leetcode.com/problems/add-two-numbers/description/

注意这样几点:

  1. 链表从左向右表示个十百......
  2. 链表长度可能不一样
  3. 最后的结果可能多出一位(5+5 = 10的情况)
TommyCpp commented 6 years ago

19. Remove Nth Node From End of List

https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/ 给定两个指针p,q 第一步,让q移动N个位置 第二步,让p,q同时向后移动,直到q移动到最后一个节点为止 此时p.next就是需要被删除的节点

TommyCpp commented 6 years ago

24. Swap Nodes in Pairs

https://leetcode.com/problems/swap-nodes-in-pairs/description/ 思考使用递归完成, 针对A->B->C->D.....的情况,首先交换好C,D及之后的节点,此时链表为A->B->D->C....,然后将B.next = A,A.next = D完成交换

TommyCpp commented 6 years ago

61. Rotate List

https://leetcode.com/problems/rotate-list/description/

  1. 首先明确,当k超过链表长度s的时候,其结果应当与k%s相同
  2. 我们的目标是找到这样一个节点t,使得在结果链表中t.next = null,原链表中t.next作为结果链表的head
  3. 因此,t应当是第count - k个节点,其中count是链表长度
TommyCpp commented 6 years ago

86. Partition List

https://leetcode.com/problems/partition-list/description/ 注意每一轮迭代之后必须将当前节点的next置为null,否则会造成循环链表

TommyCpp commented 6 years ago

109. Convert Sorted List to Binary Search Tree

https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/description/ 递归的解决问题,使用两个指针来确定中间节点,注意如果节点数量是偶数的时候应当如何处理

TommyCpp commented 6 years ago

203. Remove Linked List Elements

https://leetcode.com/problems/remove-linked-list-elements/description/

注意考虑最后一个元素等于val的情况

TommyCpp commented 6 years ago

876. Middle of the Linked List

https://leetcode.com/problems/middle-of-the-linked-list/description/ 基本操作,找到链表中点。

  1. 使用两个指针runnerwalker
  2. runner每次移动两个节点,walker每次移动一个节点
  3. 注意runner的结束条件,防止出现NullPointerException
TommyCpp commented 6 years ago

338. Counting Bits

https://leetcode.com/problems/counting-bits/description/

  1. 所有2**n1个个数肯定为1(因为他们的二进制都是类似100000....的模式)
  2. 2**n2**n + 2**(n-1)之间的数,1的个数都是2(因为他们的二进制都是类似1001,1010,1100的模式)
  3. 所以如果n & (n - 1) != 0(即n不是2的指数),则其1的个数应当等于1+n - 2**(log(n) / log(2))
TommyCpp commented 6 years ago

114. Flatten Binary Tree to Linked List

https://leetcode.com/problems/flatten-binary-tree-to-linked-list/description/

注意题目要求 in-place的进行转换,所以需要保存下root的左右子树,然后逐个进行flatten,最后将左子树的结果拼接到root的右子树上,再将右子树的结果拼接之后

TommyCpp commented 6 years ago

539. Minimum Time Difference

https://leetcode.com/problems/minimum-time-difference/description/

TommyCpp commented 6 years ago

103. Binary Tree Zigzag Level Order Traversal

https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/description/ 基于层次遍历,使用一个栈保存所有节点的子节点,然后依次出栈。

可能的提高

TommyCpp commented 6 years ago

190. Reverse Bits

https://leetcode.com/problems/reverse-bits/description/

使用n & 1取得每一位,如果是0,则res<<=1;,如果是1,则res+1;res<<=1,之后将n >>>= 1; 注意n必须无符号右移

TommyCpp commented 6 years ago

14. Longest Common Prefix

https://leetcode.com/problems/longest-common-prefix/description/ 先进行排序,这样Prefix相同的字符串会排序到一起,这时候只要对比第一个和最后一个字符串即可

TommyCpp commented 6 years ago

6. ZigZag Conversion

https://leetcode.com/problems/zigzag-conversion/description/ 通过观察,发现周期是2*n-2,在这个周期中,前n个元素不需要调整,直接放入对应行即可。后n - 2个元素需要从倒数第二行到第二行逐个填充,因而使用公式2*n - i - 2来计算对应行数

TommyCpp commented 6 years ago

145. Binary Tree Postorder Traversal

https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 题目要求使用迭代方法处理, 思路是使用一个栈stack存储节点,使用一个栈res存储结果(但是是反向的) 思考,后序遍历的反向是什么? 是root,right,left 因此,在每一轮迭代中,我们的目标是逐个向res中压入root, right, left 因此在stack不空的情况下

p = stack.pop();
res.add(p.val);
if(p.left != null){
    stack.add(p.left); //注意这里必须是先压入左节点
}
if(p.right != null){
    stack.add(p.right);
}
TommyCpp commented 6 years ago

98. Validate Binary Search Tree

https://leetcode.com/problems/validate-binary-search-tree/description/

Traversal

使用中序遍历整个二叉树肯定能得到一个递增数组,基于这个条件可以判断

Resursion

在递归函数中保持两个变量maxmin,分别表示该子树节点的上界和下界,然后判断当前root节点是否在其中,之后继续递归

TommyCpp commented 6 years ago

72. Edit Distance

https://leetcode.com/problems/edit-distance/description/ 注意DP的范围是一个有word1.length()+1行,word2.length()+1列的数组 子问题是word1的前i项,word2的前j项的编辑距离,记为d(i,j) 状态转移方程是d(i,j) = min[d(i - 1,d), d(i,j - 1), d(i -1,j -1)] + 1

TommyCpp commented 6 years ago

101. Symmetric Tree

https://leetcode.com/problems/symmetric-tree/description/

TommyCpp commented 6 years ago

3. Longest Substring Without Repeating Characters

https://leetcode.com/problems/longest-substring-without-repeating-characters/description/

使用两个指针ij来表示符合要求的子串,从头到尾遍历,如果str[j]不在Set中,则j++;如果在,则i++直至str[j]不在Set

TommyCpp commented 6 years ago

137. Single Number II

https://leetcode.com/problems/single-number-ii/description/ 当数字第一次出现的时候,它被记录在b中,此时a中对应bit位是0; 当数字第二次出现的时候,它被记录在a中,此时b中对应bit位是1;此步骤清空b中对应bit位的1 当数字第三次出现的时候,此时a中的数值被清空

最后出现两次的数在a或者b中,所以使用a|b

TommyCpp commented 6 years ago

475. Heaters

https://leetcode.com/problems/heaters/description/

  1. 首先对数组排序
  2. 然后先处理houses[i] < heaters[0]houses[j] > heaters[heaters.length - 1]的情况
  3. 之后使用两个指针分别指向housesheaters的开始位置,依次排查,直到houses[i] > heaters[t] && houses[i] < heaters[t + 1]的情况
  4. 计算houses[i]heaters[t], heaters[t + 1]的相对关系,取较大值
TommyCpp commented 6 years ago

56. Merge Intervals

https://leetcode.com/problems/merge-intervals/description/

  1. 首先按照start对数组进行排序
  2. 然后从第一个元素开始,逐个合并直到不能继续合并为止,记此时最后一个被合并的项为j
  3. j + 1开始,继续迭代
TommyCpp commented 6 years ago

298. Binary Tree Longest Consecutive Sequence

https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/description/

  1. Use DFS to search
  2. note that to start, we set the parent value of root = root.val - 1 and the cur=0
    • why ? because we add a fiction parent node of root, so the cur must be reset to 1 - 1 = 0
  3. In the loop, we set the cur = 1
TommyCpp commented 6 years ago

134. Gas Station

https://leetcode.com/problems/gas-station/description/

  1. 设置两个变量startend,分别指向gas.size()-10
  2. sum记录此时燃油剩余,初始为gas[end] - cost[end]
  3. sum > 0的时候,我们不断将end++,同时更新sum
  4. sum < 0的时候,我们开始start--,同时更新sum
  5. 如此反复,直到startend会和
  6. 此时查看sum,如果大于0,则返回start,否则不能走完一圈