分治法(二)

2. 分治法解题

2.1 Search a 2D Matrix II

题目链接:https://leetcode.com/problems/search-a-2d-matrix-ii/description/
(1)遍历矩阵
对于这个问题,很自然地想到对矩阵进行遍历,但遍历的时间复杂度为O(m*n)。显然,这不是一个好的算法。
(2)分治思想
由于行和列都是排好序的,显然可以利用这一点实现时间复杂度为O(m+n)的算法。算法大致思路如下:
遍历时间为m + n

class Solution:
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        if len(matrix) == 0:
            return False
        row, column = 0, len(matrix[0]) -  1
        row_len = len(matrix) - 1
        while (row <= row_len) and (column >= 0):
            val = matrix[row][column]
            if target == val:
                return True
            elif target > val:
                row += 1
            else:
                column -= 1
        return False

如何利用分治思想呢?显然在行列的遍历过程中使用二分搜索

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        /*
        start from the leftbotton. 
        */
        int i = matrix.size() - 1;
        int j = 0;
        while (i > - 1 && j < matrix[0].size()) {
            if (matrix[i][j] > target) {
                i = binarySearch(j, 0, i, matrix, target);
                if (matrix[i][j] == target) return true;
                i = i - 1;
            }
            else {
                j = binarySearchH(i, j, matrix[0].size() - 1, matrix, target);
                if (matrix[i][j] == target) return true;
                if (matrix[i][j] < target) j = j + 1;
            }
        }
        return false;
    }
    int binarySearch(int idx, int lo, int hi, vector<vector<int>>& matrix, int target) {
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            if (matrix[mid][idx] >= target) hi = mid;
            else lo = mid + 1;
        }
        return lo;
    }
    int binarySearchH(int idx, int lo, int hi, vector<vector<int>>& matrix, int target) {
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            if (matrix[idx][mid] >= target) hi = mid;
            else lo = mid + 1;
        }
        return lo;
    }
};


2.2 Different Ways to Add Parentheses

题目链接:https://leetcode.com/problems/different-ways-to-add-parentheses/description/
本题若直接对表达式进行组合,考虑的情况非常多,但是可以采用分治的思想将复杂的大问题化简为若干个小问题进行求解。
下面以表达式23-45为例进行分析。
在这里插入图片描述
其实就是化简为左右两部分,然后再对每一部分进行计算,直至子问题规模为1,即左右部分只有一个元素。

class Solution:
    def diffWaysToCompute(self, input):
        """
        :type input: str
        :rtype: List[int]
        """
        if input.isdigit():
            return [int(input)]
        
        res = []
        for i in range(len(input)):
            if input[i] in '+-*':
                res1 = self.diffWaysToCompute(input[:i])
                res2 = self.diffWaysToCompute(input[i+1 :])
                for j in res1:
                    for k in res2:
                        res.append(self.helper(j, k, input[i]))
        res.reverse()
        return res
    
    
    def helper(self, j, k, op):
        if op == '+':
            return j + k
        elif op == '-':
            return j - k
        else:
            return j * k      

在这里插入图片描述
显然,该方法有待改进。

猜你喜欢

转载自blog.csdn.net/qq_33254870/article/details/84847199