Leetcode 3. Longest Substring Without Repeating Characters/ 4. Median of Two Sorted Arrays[二分]

好久没有用c++写过代码了,最近没有什么事情,就像做做题。然后发现python用多了C++不会使了。。。。

1. Longest Substring Without Repeating Characters

​ Given a string, find the length of the longest substring without repeating characters.
Example 1:
Input: "abcabcbb"
​ Output: 3
​ Explanation: The answer is "abc", with the length of 3.
Example 2:
​ Input: "bbbbb"
​ Output: 1
​ Explanation: The answer is "b", with the length of 1.
Example 3:
​ Input: "pwwkew"
​ Output: 3
​ Explanation: The answer is "wke", with the length of 3.
Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

题意

给你一个字符串,找到连续的最长的字串

思路

就是最大字段和,找个数组维护一下就好了

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int cnt[500];
        for (int i = 0; i < 500; i++) cnt[i] = -1;
        int begin = 0;
        int sum = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s[i];
            if (cnt[c - ''] == -1) {
                sum = max(sum, i - begin + 1);
                cnt[c - ''] = i;
            }
            else {
                begin = max(cnt[c - ''] + 1, begin);
                cnt[c - ''] = i;
                sum = max(sum, i - begin + 1);
            }
        }
        return sum;
    }
};

2. Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
You may assume nums1 and nums2 cannot be both empty.

Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

题意

给你两个有序数组,找到它们的中位数,要求是log级别。

思路:

这个题好面熟,之前遇到过这个题,但是因为出题人的问题卡不了(O(log)),当时直接(O(n+m))sort就过了。好像考研的时候也遇到过这个题,正解如何我真的忘了。。。。
首先,通常情况下的办法是每次各从每个数组中取出一个元素,然后进行比较,得到中间值,时间复杂度是(O(n+m))
然后对上面的方法进行二分优化:
首先计算出要获得中间值需要将两个数组取出多少个元素。对于总长度(L)是奇数个,要取出([L/2])个元素,对于总长度(L)是偶数个,需要取出([(L-1)/2])个。然后二分最长的那个数组,如当前位置是(loc),那么需要从第一个数组中去掉前(loc)个元素,剩下(t)个从第二个数组中去。这样最优的情况是第一个数组(loc)上的元素仅仅比第二个数组(t)位置上的元素大,那么此时也就是使得位置(loc)和位置(t)对齐,前面的部分就直接可以去掉,中位数在每个数组的切割部分开始的两个元素所组成的四个元素的最小两个值(或一个)中取得(不确定四个元素的大小关系),即在(loc)(loc+1)(t)(t+1)四个位置中选择最小的两个或一个。如图,红色部分表示两个数组中前一半最小的元素。

有以下几种情况:
1.如果此时第二个数组不够去掉的数量,此时说明loc的位置太靠前了,需要向后移动,此时判为假。
2.如果第一个数组(loc)位置上的元素大于第二个数组(t-1)位置上的元素(如果存在的话),说明此时可能还未对齐,仍然可以向前移动。
这样每次最长的数组进行二分,复杂度为(O(log(max(n + m)))),但是仅仅超过了26.26%的C++提交。

class Solution {
public:
    void find(vector<int> n1, vector<int>n2, int& loc1, int& loc2) {
        int len1 = n1.size(), len2 = n2.size();
        bool flag = false;
        int len = len1 + len2, half = (len1 + len2 - 1)/2;
        int ub = len1 - 1, lb = 0;
        loc1 = len1/2;
        while (ub >= lb) {
            int mid = (ub + lb)>>1;
            int t = half-mid;
            flag = (t <= len2) and (t < 1 or n1[mid] > n2[t-1]);
            if (flag) {
                loc1 = mid; loc2 = t;
                ub = mid - 1;
            }
            else lb = mid + 1;
        }
        
    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        const int inf= 1e9 + 10;
        int num[4], loc1, loc2;
        int len1 = nums1.size(), len2 = nums2.size();
        if (!len1) return double((nums2[(len2-1)/2] + nums2[len2/2])/2.0);
        if (!len2) return double((nums1[(len1-1)/2] + nums1[len1/2])/2.0);
        int len = len1 + len2;
        if (len1 > len2) find(nums1, nums2, loc1, loc2);
        else find(nums2, nums1, loc2, loc1);
        num[0] = len1 > loc1? nums1[loc1]: inf;
        num[1] = len1 > loc1+1? nums1[loc1 + 1]: inf;
        num[2] = len2 > loc2? nums2[loc2]: inf;
        num[3] = len2 > loc2+1? nums2[loc2 + 1]: inf;
        sort(num, num + 4);
        if (len&1) return num[0];
        return double(num[0] + num[1])/2.0;
    }
};
原文地址:https://www.cnblogs.com/cniwoq/p/11188479.html