Datawhale|LeetCodeTencent Task01(lc2,4,5)

002 Add Two Numbers(M)

1.Problem Description

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

题意为将两个数字的每一位按逆序存储在非空链表中,要求求出两个数字之和,结果以同样的链表形式输出。

2.Analysis and Solution

思路比较简单,按照小学列竖式的加法规则按位计算。两个数字对应位数字之和加上上一轮的进位carry为sum,sum%10作为该位运算结果lastDigit存入结果链表,sum/10作为新的进位carry。若两个数字位数不相等,最后多出的部分按类似方法单独计算即可,同样需考虑进位。要注意最后一个进位的处理,不要遗漏。
因为这里使用结构体创建链表结构,需要熟悉单链表的访问方法,另外需要额外存储结果链接的头节点作为最后的输出。

3.Code

 ListNode* addTwoNums(ListNode* l1, ListNode *l2)
 {
    ListNode* l3 = new ListNode(0);
    ListNode* l3_head = new ListNode(0);
    l3_head = l3;
    
    int carry = 0, sum = 0, lastDigit = 0;
    while(l1!= nullptr && l2!= nullptr)
    {
        sum = carry + l1->val + l2->val;
        carry = sum / 10;
        lastDigit = sum % 10;
        l3->val = lastDigit;

        l1 = l1->next;
        l2 = l2->next;
        if(l1!= nullptr && l2!= nullptr)
        {
            l3->next = new ListNode(0);
            l3 = l3->next;
        }
    }
    while(l1 != nullptr)
    {
        l3->next = new ListNode(0);
        l3 = l3->next;

        sum = carry + l1->val;
        carry = sum / 10;
        lastDigit = sum % 10;
        l3->val = lastDigit;

        l1 = l1->next;
    }
    while(l2 != nullptr)
    {
        l3->next = new ListNode(0);
        l3 = l3->next;

        sum = carry + l2->val;
        carry = sum / 10;
        lastDigit = sum % 10;
        l3->val = lastDigit;
        
        l2 = l2->next;
    }
    if(carry > 0)
    {
        l3->next = new ListNode(0);
        l3 = l3->next;
        l3->val = carry; 
    }
    
    return l3_head;        
 }

004 Median of Two Sorted Arrays(H)

1.Problem Description

Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.

Follow up: The overall run time complexity should be O(log (m+n)).

题意为输入两个有序数组,求出两个数组所有数字的中位数,同时确保时间复杂度为O(log (m+n))。

2.Analysis and Solution

这道题是刚刚结束学期算法期末考试的第一道题,没想到原来是leetcode上的hard题目。当时虽知道是用二分法,但苦思冥想好久也疏理不出解法。现在也是看了网上的一些解法才稍微明白了一些。
讨论里的解法也比较多,以官方题解为例。中位数即其恰好大于小于的元素,也大于一半的元素。设两个数组A、B长度分别为m,n,将两个数组进行分割,以较小的数组为准,不妨设m<n。若数组A在m1处划分,为使A[m1]大于一半的元素,则B的划分点n1满足m1+n1=(m+n+1)/2,m1的位置通过二分法寻找。具体涉及很多细节和边界问题的讨论,也是本题目的难点,这里自己也还没搞得特别清楚,就不班门弄斧了,可以参考leetcode给出的讨论。

3.Code

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if(nums2.length < nums1.length){
            return findMedianSortedArrays(nums2,nums1);
        }
        
        int l1 = 0, r1 = nums1.length;
        int lMax = 0, rMin = 0;
        while(l1 <= r1){
            int i = l1 + (r1 - l1)/2;
            int j = (nums1.length + nums2.length + 1)/2 - i;
            int nums1_i_1 = i == 0 ? Integer.MIN_VALUE : nums1[i-1];
            int nums1_i = i == nums1.length ? Integer.MAX_VALUE : nums1[i];
            int nums2_j_1 = j == 0 ? Integer.MIN_VALUE : nums2[j-1];
            int nums2_j = j == nums2.length ? Integer.MAX_VALUE : nums2[j];

            if(nums1_i_1 <= nums2_j){
                lMax = Integer.max(nums1_i_1,nums2_j_1);
                rMin = Integer.min(nums1_i,nums2_j);
                l1 = i + 1;
            }else{
                r1 = i - 1;
            }
        } 
        
        
        return (nums1.length + nums2.length)%2 == 1 ? lMax : (lMax+rMin)/2.0;
    }
}

005 Longest Palindromic Substring(M)

1.Problem Description

Given a string s, return the longest palindromic substring in s.

题意为给出一个字符串,找出其中最长的回文子串。回文串的含义就是从左向右遍历和从右向左遍历结果相同。

2.Analysis and Solution

这道题算是比较经典的题目,可以用动态规划求解。
子问题dp[i][j]表示字符串s从第i个到第j个字符构成的子串是否为回文串。
状态转移方程为: d p [ i ] [ j ] = d p [ i + 1 ] [ j − 1 ] & & ( s [ i ] = = s [ j ] ) dp[i][j]=dp[i+1][j-1] \&\&(s[i]==s[j]) dp[i][j]=dp[i+1][j1]&&(s[i]==s[j])
初始状态为:
(1) i = = j i==j i==j时,仅有一个字符,显然是回文串,故 d p [ i ] [ j ] = t r u e dp[i][j]=true dp[i][j]=true
(2) i = = j − 1 i==j-1 i==j1时,有两个字符,若它们相同,则为回文串,否则不是,因此 d p [ i ] [ j ] = ( s [ i ] = = s [ j ] ) dp[i][j]=(s[i]==s[j]) dp[i][j]=(s[i]==s[j])
需要注意这里dp表的遍历方向,从初始状态向右上方遍历,每次找到回文串若比当前最长回文串长,则更新最长回文串,直到dp表遍历完成。

3.Code

string longsetPalindrome(string s)
{
    int len = s.length();
    bool p[len][len];
    memset(p, 0, sizeof(p));

    string ans;

    for(int i = len - 1; i >= 0; i--)
    {
        for(int j = i; j < len; j++)
        {
            if(i == j)
                p[i][j] = true;
            else if(j == i + 1)
                p[i][j] = (s[i] == s[j]);
            else
                p[i][j] = (p[i+1][j-1] && (s[i] == s[j]));
                
            if(p[i][j] && (j - i + 1 > ans.length()))
                ans = s.substr(i, j - i + 1);
                
        }
    }
    return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值