day2

101 阅读2分钟

day2

最长回文子串

  • 暴力:双指针,一个left确定“回文子串”的最左侧,right确定最右侧,验证该“回文子串”是否达标
  • 滑动窗口:用一个字符串记录需要判断的子串
  • 确定中间某个子串(按照子串字符个数的奇偶可以分为两种情况)是回文序列,只要两侧新增的内容依然是对称的即可(与第一条的区别在,第一条是遍历是确定子串的最左侧,本条是确定子串的中间位置)

一开始直接用一个flag来记录最长子串的字符数,然后发现在比较长度时,会出现二义性:right-left+1是当前子串的长度,而flag相当于是

pair<int, int> findHuiwen(const string& s, int left, int right){
        while(left>=0 && right<s.size() && s[left]==s[right]){
            left--;
            right++;
        }
        return {left+1, right-1};
    }
    string longestPalindrome(string s) {
        int len = s.size();
        if(len<2) return s;
        int flag = 0;
        // int left=0, right=0;
        string ans{""};
        for(int i=0; i<len; ++i){
            auto [L1, R1] = findHuiwen(s, i, i);
            auto [L2, R2] = findHuiwen(s, i, i+1);
            if(R1-L1+1 > flag) {
                flag = R1-L1+1;
                // right = R1;
                // left = L1;
                ans.assign(s, L1, flag); // assign的第三个参数是要copy的字符个数
            }
            if(R2-L2+1 > flag) {
                flag = R2-L2+1;
                // right = R2;
                // left = L2;
                ans.assign(s, L2, flag);
            }
        }
        return ans;
   }

看官方题解发现还能动态规划:首先是分析每一子串的状态,按照是否构成回文分成“是”与“否”;而对于回文序列,是构成对称的子串,也就是left和right对应的字符相同。跟上述第三条解法角度类似。

爬楼梯

  • 斐波那契数列

我先是用递归写的,然后当n=44后,超时;所以改成递推了(还不是很熟练申请动态数组)

int climbStairs(int n) {
        // if(n==1 || n==0) return 1;
        // return climbStairs(n-1) + climbStairs(n-2);
​
        std::vector<int> dp{0};
        dp.push_back(1);
        dp.push_back(2);
        for(int i=3; i<=n; ++i){
            
            dp.push_back(dp[i-1]+dp[i-2]);
        }
        return dp[n];
    }

寻找两个正序数组的中位数

虽然题标出来的难度是困难,但确实直接遍历就能过,虽然时间复杂度是log(m+n)吧

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res{};
        int len1 = nums1.size();
        int len2 = nums2.size();
        int p1=0, p2=0;
        while(p1<len1 && p2<len2){
            if(nums1[p1] > nums2[p2]){
                res.push_back(nums2[p2]);
                p2++;
            }else if(nums1[p1] < nums2[p2]){
                res.push_back(nums1[p1]);
                p1++;
            }else {
                res.push_back(nums1[p1]);
                res.push_back(nums1[p1]);
                p1++;
                p2++;
            }
        }
        while(p1<len1){res.push_back(nums1[p1]); p1++;}
        while(p2<len2){res.push_back(nums2[p2]); p2++;}
        float mid = res.size()%2==0 ? (float)(res[(res.size()/2)]+res[(res.size()/2-1)]) / 2 : res[(res.size()/2)];
        return mid;
    }