• Two Sum


    Two Sum III - Data structure design

    class TwoSum:
     def __init__(self):
     self.nums = []
    
        """
        @param number: An integer
        @return: nothing
        """
        def add(self, number):
            # write your code here
            self.nums.append(number)
            idx = len(self.nums) - 1
     
            # 1.始终将 number 放在数组的最后一个位置,然后将number与前面的元素进行比较,调整位置
            # 2.时间复杂度:add O(N), find O(N)
            while idx > 0 and self.nums[idx - 1] > self.nums[idx]:
                self.nums[idx-1], self.nums[idx] = self.nums[idx], self.nums[idx-1]
                idx -= 1
     
        """
        @param value: An integer
        @return: Find if there exists any pair of numbers which sum is equal to the value.
        """
        def find(self, value):
            # write your code here
            left, right = 0, len(self.nums) - 1
            while left < right:
                s = self.nums[left] + self.nums[right]
                if s < value:
                    left += 1
                elif s > value:
                    right -= 1
                else:
                    return True
            return False




    class TwoSum:
        # 时间复杂度:add O(1), find O(N^2)
        def __init__(self):
            self.nums2cnt = {}
        """
        @param number: An integer
        @return: nothing
        """
        def add(self, number):
            # write your code here
            self.nums2cnt[number] = self.nums2cnt[number] + 1 if number in self.nums2cnt else 1
                
        """
        @param value: An integer
        @return: Find if there exists any pair of numbers which sum is equal to the value.
        """
        def find(self, value):
            # write your code here
            for num1 in self.nums2cnt:
                num2 = value - num1
                num2_cnt = 2 if num1 == num2 else 1
                if num2 in self.nums2cnt and self.nums2cnt[num2] >= num2_cnt:
                    return True
            return False

    Two Sum IV - Input is a BST

    方法1:extra space

    """
    Definition of TreeNode:
    class TreeNode:
        def __init__(self, val):
            self.val = val
            self.left, self.right = None, None
    """
    
    class Solution:
        """
        @param: : the root of tree
        @param: : the target sum
        @return: two numbers from tree which sum is n
        """
        def in_order(self, root, n, node_set):
            if not root: return 
            self.in_order(root.left, n, node_set)
            if root.val in node_set:
                self.res = [n - root.val, root.val]
            else:
                node_set.add(n - root.val)
            self.in_order(root.right, n, node_set)
    
        def twoSum(self, root, n):
            # write your code here
            if not root: return 
            self.res = None
            node_set = set()
            self.in_order(root, n, node_set)
            return self.res

    方法2:在中序序列上进行双指针

    """
    Definition of TreeNode:
    class TreeNode:
        def __init__(self, val):
            self.val = val
            self.left, self.right = None, None
    """
    
    class Solution:
        # 基于 predecessor 与 successor + 双指针 Time O(h * n) Space O(1) 
        # 448. Inorder Successor in BST 
        # 915. Inorder Predecessor in BST
        """
        @param: : the root of tree
        @param: : the target sum
        @return: two numbers from tree which sum is n
        """
    
        def twoSum(self, root, n):
            # write your code here
            if not root: return
            # 在中序序列上进行二分
            min_node = self.get_min_node(root)
            max_node = self.get_max_node(root)
            left_node, right_node = min_node, max_node
    
            while left_node != right_node:
                pivot = left_node.val + right_node.val
                if pivot == n:
                    return [left_node.val, right_node.val]
                elif pivot < n:
                    left_node = self.get_successor_node(root, left_node)
                else:
                    right_node = self.get_predecessor_node(root, right_node)
                
            return 
        
        def get_min_node(self, root):
            node = root
            while node.left:
                node = node.left
            return node
        
        def get_max_node(self, root):
            node = root
            while node.right:
                node = node.right
            return node
    
        def get_successor_node(self, root, p):
            # 找中序序列中第一个比p大的元素
            node, upper = root, None
            while node:
                # 当前node大于p,那么当前node向左走
                if node.val > p.val:
                    upper = node
                    node = node.left 
                # 当前node小于p,那么当前node向右走
                else:
                    node = node.right
            return upper 
    
        def get_predecessor_node(self, root, p):
            # 找中序序列中第一个比p小的元素
            node, lower = root, None
            while node:
                if node.val < p.val:
                    lower = node
                    node = node.right
                else:
                    node = node.left
            return lower
            

    1879 · Two Sum VII

    * sorted in ascending order of absolute value

    * O(n) time complexity and O(1) O(1) extra space

    方法1:use extra space

    def two_sum_v_i_i(self, nums: List[int], target: int) -> List[List[int]]:
            # write your code here
            self.dic = {}
            res = []
    
            for idx, num in enumerate(nums):
                if target - num in self.dic:
                    if idx < self.dic[target - num]:
                        res.append([idx, self.dic[target - num]])
                    else:
                        res.append([self.dic[target-num], idx])
                else:
                    self.dic[num] = idx
            
            return res

    方法2:xxx在数组的max和min中进行二分

    from typing import (
        List,
    )
    
    class Solution:
        """
        @param nums: the input array
        @param target: the target number
        @return: return the target pair
        """
        def two_sum_v_i_i(self, nums: List[int], target: int) -> List[List[int]]:
            # write your code here
            n = len(nums)
            if not nums: return 
    
            left, right = 0, 0
            for i in range(n):
                if nums[i] > nums[right]: right = i
                if nums[i] < nums[left]: left = i
    
            res = []
            while left >= 0 and right < n and nums[left] < nums[right]:
                if nums[left] + nums[right] < target:
                    left = self.nextleft(nums, left)
                elif nums[left] + nums[right] > target:
                    right = self.nextright(nums, right)
                else:
                    if left < right: res.append([left, right])
                    else: res.append([right, left])
    
                    left = self.nextleft(nums, left)
            return res
            
        def nextleft(self, nums, left):
            n = len(nums)
            # 如果要查找 负数left的 后一个元素(left+1)
            if nums[left] < 0:
                # 如果left左边有负数,那么left的下一个元素就是其左边的第一个负数
                for i in range(left - 1, -1, -1):
                    if nums[i] < 0:
                        return i
                # 如果left左边没有负数,那么left的下一个元素就是从0到n的第一个正数
                for i in range(n):
                    if nums[i] >= 0:
                        return i
                return -1
    
            # 如果left是正数, 那么left的下一个元素就是其右边的第一个正数
            for i in range(left + 1, n):
                if nums[i] >= 0:
                    return i 
            return -1
        
    
        def nextright(self, nums, right):
            n = len(nums)
            # 如果要查找 正数right的 前一个元素(right-1)
            if nums[right] > 0:
                # [0,-1,2,-3,4] 中的 4
                # 如果right左边有正数,那么right的前一个元素就是从右向左第一个大于0的数
                for i in range(right-1, -1, -1):
                    if nums[i] > 0: 
                        return i
                # 如果right左边全是非正数,那么right的前一个元素就是从0到n的第一个非正
                # [0,-1,2,-3,4] 中的 2
                for i in range(n):
                    if nums[i] <= 0:
                        return i
                return -1
    
            # 如果要查找 非正数right 的前一个元素。从right到右的第一个负数
            # [0,-1,2,-3,4] 中的-1
            for i in range(right+1, n):
                if nums[i] <= 0:
                    return i
    
            return -1
     

    443 · Two Sum - Greater than target

     
     
     
     
     
     

  • 相关阅读:
    团队项目-需求分析报告
    团队项目-选题报告
    第一次结对编程作业
    第一次个人编程作业
    软件工程作业(一)
    期末总结
    第04组 Beta冲刺(2/5)
    第04组 Beta冲刺(3/5)
    第04组 Beta冲刺(4/5)
    第04组 Beta冲刺(5/5)
  • 原文地址:https://www.cnblogs.com/zijidan/p/16127315.html
Copyright © 2020-2023  润新知