154. Find Minimum in Rotated Sorted Array II \ 128. Longest Consecutive Sequence

154. Find Minimum in Rotated Sorted Array II

题目解析

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

The array may contain duplicates.

这道题目在查找的东西就是数组中的最小的数字,因为这个数组是由一个升序数组旋转之后得来的,所以很明显可以使用二分法计算最小值。

同时可以使用暴力破解,找到最小值,因为只要找到第一个比nums[0]更小的数字,那么就是最小的数字。

代码实现

暴力破解:

class Solution {
public:
    int findMin(vector<int>& nums) {
        int len = nums.size();
        if(len == 1) return nums[0];
        int min = nums[0];
        for(int ind = 1; ind < len; ind++) if(nums[ind] < min) return nums[ind];
        return min;
    }
};

二分法:

class Solution {
public:
    int findMin(vector<int>& nums) {
        int len = nums.size();
        if(len == 1) return nums[0];

        int high = len - 1, low = 0, mid = (low + high) >> 1;
        while(low+1 < len && nums[low] == nums[low+1]) low++;
        while(high-1 >= 0 && nums[high] == nums[high-1]) high--;
        while(low < high) {
            mid = (low + high) >> 1;
            if(nums[low] > nums[mid] || nums[high] > nums[mid]) high = mid;
            else low = mid + 1;
            while(low+1 < len && nums[low] == nums[low+1]) low++;
            while(high-1 >= 0 && nums[high] == nums[high-1]) high--;
        }
        return nums[low];
    }
};

在leetcode上发现,还是暴力直接查找最小值更快一些。可能和测试例子有关系。在去除有重复项这一块,我做的改变是计算最高和最低索引的时候去掉重复项。然后low的索引就是逼近最小值,然后high的索引就是用来去除不符合的范围。

128. Longest Consecutive Sequence

题目描述

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

Your algorithm should run in O(n) complexity.

找到最长的序列的长度。

代码实现

法一:使用排序,再计算最长的长度

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int len = nums.size();
        if(!len) return 0;
        sort(nums.begin(), nums.end());
        int min = 1, cnt = 0;
        for(int i = 0; i < len; i++) {
            cnt = 1;
            while(i+1 < len && (nums[i] + 1 == nums[i+1] || nums[i] == nums[i+1])) { 
                if(nums[i] != nums[i+1])  cnt++; 
                i++;  
            }
            if(cnt > min) min = cnt;
        }
        return min;
    }
};

法二:使用map数据结构进行计算

class Solution {
public:
    int longestConsecutive(vector<int>& num) {
        unordered_map<int, int> m;
        int r = 0;
        for (int i : num) {
            if (m[i]) continue;
            r = max(r, m[i] = m[i + m[i + 1]] = m[i - m[i - 1]] = m[i + 1] + m[i - 1] + 1);
        }
        return r;
    }
};

这里的做法就是把一个序列的两端设置成它的长度,然后进行计算新的加入的序列的长度就是把m[i + 1] + m[i - 1] + 1)。 在更新数据的时候不是整个序列的长度都更新,这里更新的数据是在序列的两端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值