Friedrich Ewald My Personal Website

Recent Posts


  • Leetcode: Single number

    Given a list of integers [1,1,2], there is only one number which is not repeated. The numbers can be in any order. The minimum length of the array is 1. Numbers can be negative or positive. The algorithm should have a time complexity of O(n) and a space complexity should be constant O(1). Given this information, we can use the properties of a set or a map.

    Continue reading

  • Leetcode: First unique character in string

    Given a string s, find the first non-repeating character in it and return its index. If it does not exist, return -1. An example is the word leetcode where the l only appears once, therefore returning 0 as result. The obvious, but very slow, solution is to iterate over the string and then for ever character, check the whole string if the character appears again. This has a time complexity of O(n^2). A better solution is to write all characters in a map and count the number of occurrences. This way, we can iterate again and simply look at the counter in the map. This yields a time complexity of O(2n).

    Continue reading

  • Leetcode: Symmetric tree

    The task is to determine if a tree is symmetric, meaning mirrored along the root node. The usual tree structure is given in form of a TreeNode.

    class TreeNode:
      def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
    A symmetric tree looks like this:
    Note that the 3 and 4 are flipped in the left vs. right branch.
    
             1
           /   \
          2     2
         / \   / \
        3   4 4   3
    
    
    An asymmetric tree looks like this:
    Note that the 3 would need to be on the other side of 
    either branch to make this tree symmetric.
    
             1
           /   \
          2     2
         /     /
        3     3
    The logic itself is quite straightforward look at two nodes and compare the values. If their respective values are the same look at both of their children and compare them. Repeat this process until every node is visited. There are some special cases here that need to be handled. The left child can be None while the right child is not and vice versa. If both children are None, return True and do not proceed because this means we reached a leaf node.

    Continue reading

  • Leetcode: Binary tree inorder traversal

    The task is to traverse a binary tree inorder. This means, that starting from the root node, nodes should be visited in the following order: left, self, right. With this knowledge it is easy to come up with a recursive algorithm. The only special case that needs to be handled are the leaf nodes that don’t have any children. By still visiting the non-existing children and then returning an empty list ([]) when a None is encountered, the whole algorithm fits into two lines.

    class TreeNode:
      def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
    class Solution:
      def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        # Handle non-existing leaf-nodes (including empty root)
        if root is None:
          return []
        
        # Visit left - current - right
        return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
    
    
    if __name__ == '__main__':
      s = Solution().inorderTraversal
      print(s(TreeNode(1, None, TreeNode(2, TreeNode(3), None))), [1,3,2])
    Runtime: 41 ms, faster than 70.32% of Python3 online submissions for Binary Tree Inorder Traversal. Memory Usage: 13.8 MB, less than 60.08% of Python3 online submissions for Binary Tree Inorder Traversal.

  • Leetcode: Square root of x

    The task is to implement a square root method without using math.sqrt or ** or pow or any similar function. Any digits after the decimal point do not to be returned. This is effectively the floor(sqrt(n)) function. The first idea is to simply try out every number and multiply it with itself until the square root is found. If the next number is greater than n, return the previous number. This is however not very efficient as it has a time complexity of O(sqrt(n)) in every case. To speed this process up, we can use binary search. The idea is to always double the size of the steps until we reach the target number or overshoot. If we overshoot, take half of the number and start at 1 again, then double, and so on.

    Continue reading

Page: 16 of 33