DP (10) -- Wiggle Subsequence,Search a 2D Matrix II

7 篇文章 0 订阅

Wiggle Subsequence

A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.

For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, [1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.

Examples:

Input: [1,7,4,9,2,5]
Output: 6
The entire sequence is a wiggle sequence.

Input: [1,17,5,10,13,15,10,5,16,8]
Output: 7
There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].
解法1:感觉属于贪心

1. 思路类似于Increasing Subsequence;使用一个vector记录目前最长的wiggle subsequence。

2. 如果之前是上升趋势且当前数字比vector的尾部数字大,则使用当前数字替换尾部数字,因为更大的数更有可能产生wiggle;下降趋势同理;如果大小关系与趋势相反则push到vector中。

3. 以下改写为O(1),因此只需要记录vector的最后一个值

    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size() < 2) return nums.size();
        int last = nums[0];
        int count = 1;
        bool positive = false;
        int i = 1;
        while(nums[i] == last) i++;
        if(i >= nums.size()) return 1;
        positive = nums[i] > last ? true : false;
        last = nums[i++];
        count++;
        for(; i < nums.size(); i++){
            if(nums[i] > last){
                if(!positive) count++;
                last = nums[i];
                positive = true;
            }else if(nums[i] < last){
                if(positive) count++;
                last = nums[i];
                positive = false;
            }
        }
        return count;
    }


解法2:贪心

1. ends_small表示上次以下降结尾的最长序列长度,ends_large表示上次以上升结尾的最长序列长度。

    int wiggleMaxLength(vector<int>& nums) {
        if (nums.empty()) return 0;
        int len = nums.size();
        int ends_large = 1;	//如果一直是下降的,ends_large是不变的;
        int ends_small = 1;
        for (int i = 1; i < len; i++) {
            if (nums[i] < nums[i-1]) ends_small = ends_large + 1;	//nums[i]<nums[i-1,说明nums[i] < preLarge(preLarge不一定是i-1,可能是前面很多个)
            else if (nums[i] > nums[i-1]) ends_large = ends_small + 1;
        }
        return max(ends_small, ends_large);
    }


Search a 2D Matrix II

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.

解法1: 从右上角开始找,如果target小于右上角,右上角所在列可以被排除;如果target大于右上角,则右上角所在行可以被排除。这样我们每次都可以排除一行或一列,直到找到target或者越界

    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.empty() || matrix[0].empty()) return false;
        int m = matrix.size();
        int n = matrix[0].size();
        int row = 0, col = n - 1;
        while(col >= 0 && row < m){
            if(matrix[row][col] == target) return true;
            else if(target < matrix[row][col]) col--;
            else if(target > matrix[row][col]) row++;
        }
        return false;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值