算法练习(2)—— 简单分治

算法练习(2)—— 简单分治

前言

分治不仅仅是分而治之这么一个简单的道理思想,其中蕴含的各种各样的优化方法才是其最大的魅力及难点…很明显大部分这类题目都在复杂度上有一定的要求。
这次做的题目虽然是medium难度,而且跟分治没有很大关系,做起来还是相当轻松的~

习题

这次的题目在leetcode算法题中的Divide and Conquer栏目中的第240题:
Search a 2D Matrix II


老规矩,上题:

Description

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

  • Integers in each row are sorted in ascending from left to right.
  • Integers in each column are sorted in ascending from top to bottom.

Example

Consider the following matrix:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]

Given target = 5, return true.
Given target = 20, return false.

思路与代码

1.首先理解一下题意,就是给你一个按已知顺序排好序的矩阵(具体顺序是右边一定比左边大,下边一定比上边大)。目的是给你一个target,看它是否在矩阵中。
2.接下来讨论可行的方法:

  • 从头到尾扫描一遍,有即有,无即无。这是最蠢的办法,既然矩阵给你排好序了,肯定有更好更简单的搜索方法。因此这个方法肯定要弃用

  • 上面那个想法就涉及到起点选择在哪里的问题。一开始想到的是左上角,但是因为这个矩阵的特点,我们知道左上角和右下角分别是数的最小值和最大值。遇到最差的情况,比如说从左上角开始扫描,但是那个数值偏大,可能要扫描很多次。因此有两个选择可能比较好,一个是选择矩阵的中心点,另一个是选择左下角或者右上角。

  • 选择矩阵的中心点可能会遇到一些问题。比如说当行数和列数不是奇数的时候不好选取。以及从中间向两边出发的结束条件其实是出边界与否。因此不如直接选取左下角或者右上角。在题目所给的例子中,也可以看出18和15比较接近于30的一半,可以说是比较理想的数字…所以最后决定用左下角或右上角作为搜索的起点,搜索判断终止的条件是出矩阵边界与否。

3.最后写出来的代码相当简单:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if (matrix.empty())
            return false;

        int row = matrix.size();
        int col = matrix[0].size();

        // 选取左下角作为搜索的起点
        int x = row - 1, y = 0;
        while (x >= 0 && y < col) {
            if (matrix[x][y] == target)
                return true;
            if (matrix[x][y] < target)
                y++;
            else
                x--;
        }
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值