leetcode题解日练--2016.7.13

日练三题,冰冻三尺非一日之寒。

今日题目:1、猜数字高低;2、2维矩阵查找II;3、二维矩阵查找;4、旋转图像;5、颜色排序。

今日摘录:

憎恨伤不了对方一根寒毛,却把自己的日子弄成了炼狱。
——卡耐基 《人性的弱点》

374. Guess Number Higher or Lower | Difficulty: Easy

We are playing the Guess Game. The game is as follows:

I pick a number from 1 to n. You have to guess which number I picked.

Every time you guess wrong, I’ll tell you whether the number is higher or lower.

You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0):

-1 : My number is lower
1 : My number is higher
0 : Congrats! You got it!
Example:
n = 10, I pick 6.

Return 6.

题意:猜数字游戏,相信很多人有有玩过。

思路:
今日新题,很简单的一个二分思想,没什么好写的。

// Forward declaration of guess API.
// @param num, your guess
// @return -1 if my number is lower, 1 if my number is higher, otherwise return 0
int guess(int num);

class Solution {
public:
    int guessNumber(int n) {
        int left = 1,right=n;
        while(left<right)
        {
            int mid = left+(right-left)/2;
            int res = guess(mid);
            if(res==1)  left = mid+1;
            else if(res==-1)    right = mid-1;
            else    return mid;
        }
        return right;
    }
};

结果:0ms

240. Search a 2D Matrix II | Difficulty: Medium

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.
For 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.

题意:找一个数字是否在矩阵当中。矩阵的特点是从左到右递增,从上到下递增。

思路:
通过观察矩阵,可以看到一个很有趣的地方,以题目举例的矩阵来说,以右上角顶点15作为顶点,当查找5的时候,查找轨迹是向左,向左,向左,向下,找到,查找20的轨迹是向下,向下,返回失败。
没错,就是在查找中,待查找的数大了就向下,小了就向左。不难写出代码:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size();
        int n=matrix[0].size();
        int i=0,j=n-1;
        while(matrix[i][j]!=target)
        {
            if(matrix[i][j]>target)     j--;
            else if(matrix[i][j]<target)    i++;
            if(i>=m||j<0)   return false;
        }
        return true;
    }
};

结果:216ms

74. Search a 2D Matrix | Difficulty: Medium

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 from left to right.
The first integer of each row is greater than the last integer of the previous row.
For example,

Consider the following matrix:

[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
Given target = 3, return true.

题意:和上题类似,在矩阵中进行搜索,不同之处在于这个矩阵加了一个限制就是下面的行的任意元素均大于上面的行。

思路:我是先从每行首元素中去找不大于target的最大行,然后再从那行中去找target,复杂度是O(log(m)*log(n))
1、

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size(),n=matrix[0].size();
        int low = 0,high=m-1;
        int row;
        while(low<=high)
        {
            int mid=low+(high-low)/2;
            if(matrix[mid][0]>target) high=mid-1;
            else if(matrix[mid][0]<target)    low = mid+1;
            else return true;
        }
        if(high<0)  row=0;
        else row= high;
        low=1,high=n-1;
        while(low<=high)
        {
            int mid=low+(high-low)/2;
            if(matrix[row][mid]>target) high = mid-1;
            else if (matrix[row][mid]<target)   low = mid+1;
            else    return true;
        }
        return false;
    }
};

结果:12ms
update:2016.9.8

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size(),n=matrix[0].size();
        int l = 0,r = m-1;
        int row;
        while(l<r)
        {
            int mid  =l+(r-l+1)/2;
            if(matrix[mid][0]<target) l = mid;
            else if(matrix[mid][0]>target) r = mid-1;
            else    return true;
        }
        if(r<0)   row = 0;
        else    row = r;
        l=0,r = n-1;
        while(l<=r)
        {
            int mid  =l+(r-l)/2;
            if(matrix[row][mid]<target) l = mid+1;
            else if(matrix[row][mid]>target) r = mid-1;
            else    return true;
        }
        return false;
    }
};

结果:9ms

2、直接将一个矩阵看成一个向量,即将其平铺成向量,然后再用二分查找。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size(),n=matrix[0].size();
        int low = 0,high=m*n-1;
        while(low<=high)
        {
            int mid=low+(high-low)/2;
            if(matrix[mid/n][mid%n]>target) high=mid-1;
            else if(matrix[mid/n][mid%n]<target)    low = mid+1;
            else return true;
        }
        return false;
    }
};

结果:15ms

48. Rotate Image | Difficulty: Medium

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Follow up:
Could you do this in-place?

题意:将一个矩阵顺时针旋转90度。

思路:
1、如果复制一个新的矩阵出来,很容易写出代码。

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
     int m=matrix.size();
     vector<vector<int>> res(matrix);
     for(int i=0;i<m;i++)
     {
         for(int j=0;j<m;j++)
         {
             matrix[i][j] = res[m-1-j][i];
         }
     }
    }
};

结果:4ms

2、题目中说了,不用额外的空间去做这道题。想了一阵子没想出来方法,就参考了下讨论中https://discuss.leetcode.com/topic/6796/a-common-method-to-rotate-the-image的解法。
顺时针旋转的大概思路就是这样。

 1 2 3         7 8 9      7 4 1
 4 5 6     - > 4 5 6   -> 8 5 2
 7 8 9         1 2 3      9 6 3

逆时针的话应该是

 * anticlockwise rotate
 * first reverse left to right, then swap the symmetry
 * 1 2 3     3 2 1     3 6 9
 * 4 5 6  => 6 5 4  => 2 5 8
 * 7 8 9     9 8 7     1 4 7
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
     reverse(matrix.begin(),matrix.end());
     int m=matrix.size();
     for(int i=0;i<m;i++)
     {
         for(int j=i+1;j<m;j++)
           swap(matrix[i][j],matrix[j][i]);
     }
    }
};

结果:8ms

75. Sort Colors | Difficulty: Medium

Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note:
You are not suppose to use the library’s sort function for this problem.

题意:一个向量里面有0 、1、2三种数,在不用库函数的前提下将它们排序。

思路:
1、直接遍历一遍计数,然后重写一下向量就可以了。

class Solution {
public:
    void sortColors(vector<int>& nums) {
        unordered_map<int,int> maps;
        int k=0;
        for(auto num:nums)
            maps[num]++;
        for(int i=0;i<3;i++)
        {
            int size = maps[i];
            while(size--)   nums[k++]=i;
        }
    }
};

结果:4ms

2、从左往右,设置一个左标志和右标志,每次碰到0就将其和左标志换同时左标志向右移1,每次碰到2就将其和右标志交换同时右标志左移1。

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int left=0,right=nums.size()-1;
        for(int i=0;i<=right;i++)
        {
            while(nums[i]==2&&i<right)  swap(nums[i],nums[right--]);
            while(nums[i]==0 && i>left)  swap(nums[i],nums[left++]);
        }
    }
};

结果:4ms

3、还有种很巧妙的方法

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n0 = -1, n1 = -1, n2 = -1;
    for (int i = 0; i < nums.size(); ++i) {
        if (nums[i] == 0) 
        {
            nums[++n2] = 2; nums[++n1] = 1; nums[++n0] = 0;
        }
        else if (nums[i] == 1) 
        {
            nums[++n2] = 2; nums[++n1] = 1;
        }
        else if (nums[i] == 2) 
        {
            nums[++n2] = 2;
        }
    }
    }
};

结果:4ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值