LeetCode 力扣 刷题记录(1-5)题目+算法分析+Cpp解答

1.Two Sum

一次哈希:

​ 将数值作为索引,在哈希表中找此时数值对应的另一个数值,若存在则取出该数值的编号,若不存在则将此时的数值和它的编号存入哈希表,以供后面使用。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> m;
        vector<int> ans;
        int len = nums.size();
        for(int i=0;i<len;i++){
            int n = target - nums[i];
            if(m.find(n) != m.end()){
                ans.push_back(m[n]);
                ans.push_back(i);
                return ans;
            }
            m[nums[i]] = i;
        }
        return ans;
    }
};

2.Add Two Numbers

考虑多种情况:

​ 链表可能不一样长,最后一位也可能会进位(最后需要再判断进位carry)。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* index = new ListNode();
        ListNode* ans = index;
        int carry = 0;
        while(l1 != NULL && l2 != NULL){
            index->next = new ListNode();
            index = index->next;
            int sum = l1->val + l2->val + carry;
            if(sum>9){
                sum = sum - 10;
                carry = 1;
            }
            else
                carry = 0;
            index->val = sum;
            l1 = l1->next;
            l2 = l2->next;
        }
        if(l1 == NULL && l2 != NULL)
            l1 = l2;
        while(l1 != NULL){
            index->next = new ListNode();
            index = index->next;            
            int sum = l1->val + carry;
            if(sum>9){
                sum = sum - 10;
                carry = 1;
            }
            else
                carry = 0;
            index->val = sum;
            l1 = l1->next;
        }
        if(carry == 1){
            index->next = new ListNode();
            index = index->next;
            index->val = carry;
        }
        return ans->next;
    }
};

3.Longest Substring Without Repeating Characters

动态规划:

判断字符串为空,返回0。

判断字符串不为空:动态规划:局部最优 --> 整体最优

​ 从字符串第二个字符开始判断到字符串的最后一个字符。

记录两个数据:

  1. 到达该字符时 满足要求的字符串的 最大长度:ans

  2. 到达该字符时 以该字符串结尾的 满足要求的字符串的 长度:dp

    (只有加入后面来的字符,才可能使得 满足要求的字符串 更长)

每判断一个字符,比较一次 ans 和 dp 的大小,保证 局部最优。

最后的 ans 便是答案:整体最优。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty())
            return 0;
        int len = s.length();
        int ans = 1,dp = 1,temp = 0;
        for(int i=1;i<len;i++){
            for(temp=0;temp<dp;temp++){
                if(s[i] == s[i-1-temp])
                    break;
            }
            dp = temp+1;
            ans = max(ans,dp);
        }
        return ans;
    }
};

4.Median of Two Sorted Arrays

二分法:

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len1 = nums1.size();
        int len2 = nums2.size();
        if(len1 > len2)
            return findMedianSortedArrays(nums2,nums1);
        int mid = (len1 + len2 + 1)/2;
        int min1 = 0, max1 = len1,i,j;
        while(min1 <= max1){
            i = (min1 + max1)/2;
            j = mid - i;
            if(i < len1 && nums1[i] < nums2[j-1])
                min1 = i+1;
            else if(i > 0 && nums1[i-1] > nums2[j])
                max1 = i-1;
            else{
                double max_of_left = max(i > 0 ? nums1[i-1]: INT_MIN, 
                                         j > 0 ? nums2[j-1]: INT_MIN);
                if((len1 + len2) & 1)
                    return max_of_left;
                double min_of_right = min(i < len1 ? nums1[i]: INT_MAX, 
                                          j < len2 ? nums2[j]: INT_MAX);
                return 0.5 * (max_of_left + min_of_right);
            }
        }
        return -1;
    }
};

5.Longest Palindromic Substring

动态规划:

​ 初始化长度为 1 的回文子串:dp[ i ] [ i ];

​ 初始化长度为 2 的回文子串:

​ 需要满足:s [ i ] = s [ i+1 ],dp[ i ] [ i+1 ] 就为 1;

​ 循环判断长度从 3 到 s.length() 的回文子串:设此时回文子串的长度为 n

​ 循环回文子串的开始位置:i,从 0 开始,到 s.length() - n 结束。

​ 需要满足:s [ i ] = s [ i+n-1 ];

​ 并且从 i+1 开始,到 i+n-2 结束的子串为回文子串,即 dp[ i+1 ] [ i+n-2 ] = 1。

​ 循环的过程中不断更新回文子串的最大长度和开始位置。

class Solution {
public:
    string longestPalindrome(string s) {
        int len = s.size();
        if(len == 0 || len == 1)
            return s;
        int start = 0,maxlen = 1;
        vector<vector<int>> dp(len,vector<int>(len));
        for(int i=0;i<len;i++){
            dp[i][i] = 1;
            if(i < len-1 && s[i] == s[i+1]){
                dp[i][i+1] = 1;
                maxlen = 2;
                start = i;
            }
        }
        for(int n = 3;n <= len;n++){
            for(int i=0;i<=len-n;i++){
                if(s[i] == s[i+n-1] && dp[i+1][i+n-2] == 1){
                    dp[i][i+n-1] = 1;
                    if(maxlen < n){
                        start = i;
                        maxlen = n;
                    }
                }
            }
        }
        return s.substr(start,maxlen);
    }
};

中心扩展:

​ 把字符串的某个字符,或者是某两个相邻字符之间的位置作为中心;

​ 以中心为基准,向两边扩展,如果两边相同,则为回文子串。

​ 循环遍历字符串中的中心位置,讨论以此为中心的回文子串。

​ 不断更新回文子串的最大长度和开始位置。

class Solution {
public:
    string longestPalindrome(string s) {
        int len = s.length();
        if(len == 0 || len == 1)
            return s;
        int start = 0,maxlen = 1;
        for(int i=0;i<len;i++){
            int begin = i,end = i;
            while(begin-1 >= 0 && end+1 < len){
                if(s[begin-1] == s[end+1]){
                    begin = begin -1;
                    end = end + 1;
                    if(maxlen < (end - begin + 1)){
                        maxlen = end - begin + 1;
                        start = begin;
                    }
                }
                else
                    break;
            }
            begin = i;
            end = i+1;
            while(begin >= 0 && end < len){
                if(s[begin] == s[end]){
                    if(maxlen < (end - begin + 1)){
                        maxlen = end - begin + 1;
                        start = begin;
                    }
                    begin -= 1;
                    end += 1;
                }
                else
                    break;
            }
        }
        return s.substr(start,maxlen);
    }
};
发布了36 篇原创文章 · 获赞 5 · 访问量 5230

猜你喜欢

转载自blog.csdn.net/qq_43413123/article/details/104925618
今日推荐