Leetcode寒假刷题 Day01


前言

之前报名了DataWhale的LeetCode腾讯精选50题的组队刷题班,正好也借助寒假的时间来提升自己的编程能力和思维能力,同时也能交到一些志同道合的朋友,因此从今天开始,我就正式开始刷LeetCode腾讯精选练习题,也希望我的博客能给大家带来启发。

一、002 两数相加

1. 题目描述

题号:2
难度:中等
两数相加
给出两个非空链表,用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储一位数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

示例 2:

输入:(3 -> 7) + (9 -> 2)
输出:2 -> 0 -> 1
原因:73 + 29 = 102

2. 解题思路

我最先做这道题时,没有考虑到大数相加的情况,因此直接用了 int 类型的变量作为中间变量,结果导致不能通过全部测试用例,换成 double 过后虽然能通过更多的测试用例,但是仍然不能通过所有的测试用例。因此,考虑用字符串或者直接用ListNode链表。

由于字符串还需要进行中间操作,浪费时间的同时,也增加了额外的存储开销,因此考虑直接用链表操作。

考虑到了两数相加的时候,从个位开始进行,且要么有进位,要么没有进位,进位只能为1,按照这一思想编写代码。

3. 代码实现

  • 1568 / 1568 个通过测试用例
  • 状态:通过
  • 语言:Java
  • 执行用时: 2 ms 击败100%
  • 内存消耗: 38.9 MB 击败41%
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
         ListNode tail=new ListNode((l1.val+l2.val)%10,null);
        ListNode node=tail;
        ListNode node1=null;
        int addBit=(l1.val+l2.val)/10;
        while(((l1.next)!=null)&&((l2.next)!=null))
        {
            l1=l1.next;
            l2=l2.next;
            node1=new ListNode((l1.val+l2.val+addBit)%10,null);
            tail.next=node1;
            tail=tail.next;
            addBit=(l1.val+l2.val+addBit)/10;
        }
        while(((l1=l1.next)!=null))
        {
            node1=new ListNode((l1.val+addBit)%10,null);
            tail.next=node1;
            tail=tail.next;
            addBit=(l1.val+addBit)/10;
        }
        while(((l2=l2.next)!=null))
        {
            node1=new ListNode((l2.val+addBit)%10,null);
            tail.next=node1;
            tail=tail.next;
            addBit=(l2.val+addBit)/10;
        }
        if(addBit==1)
        {
            tail.next=new ListNode(1,null);
            tail=tail.next;
        }
        return node;
    }

二、004 寻找两个正序数组的中位数

1. 题目描述

题号:4
难度:困难
寻找两个正序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5

2. 解题思路

两个有序数组的合并和排序,是典型的归并排序的问题。由于考研的时候学过归并排序,因此一遍过。时间复杂度为 O(log(m + n))。

3. 代码实现

  • 2091 / 2091 个通过测试用例
  • 状态:通过
  • 语言:Java
  • 执行用时: 3 ms 击败83%
  • 内存消耗: 39.5 MB 击败92%
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int i=0,j=0,k=0;
        int []nums=new int[nums1.length+nums2.length];
        while(i<nums1.length&&j<nums2.length)
        {
            if(nums1[i]<nums2[j])
            {
                nums[k++]=nums1[i++];
            }
            else
            {
                nums[k++]=nums2[j++];
            }
        }
        while(i<nums1.length)
            nums[k++]=nums1[i++];
        while(j<nums2.length)
            nums[k++]=nums2[j++];
        if(nums.length%2==1)
        {
            return nums[nums.length/2];
        }
        else
        {
            return (double)(nums[nums.length/2-1]+nums[nums.length/2])/2;
        }
    }

三、005 最长回文子串

1. 题目描述

题号:5
难度:中等
最长回文子串
给定一个字符串 s,1<=s.length<=1000,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

示例 2:

输入: “cbbd”
输出: “bb”

示例 3:

输入: “a”
输出: “a”

2. 解题思路

本题首先自然是想到暴力破解,但是提交后发现超出了时间限制。这里引入一个概念,叫做中心扩展法。对于本题的回文而言,若假设以“a”为中心的最大长度为X,显然X>=1。若a的周围两数相等,则X+=2。即,以某一基础点为中心(长度为1或者2)向两边扩散的最长回文数,如果p(i-j,i+j)是回文数,则p(i-j+1,i+j-1)(j>=1)必定是回文数。即长的字符串是回文子串,则去掉头和尾的一个数字后也必然是回文数(如果长度>2)。在具体写代码时,用flag变量注明基本的扩展点的长度为1还是为2。并且由于题目需要的返回值是一个字符串,而不是最长回文子串的长度,因此我并没有用一个变量去记录这个长度,而只是记录了相对于中心的基本点浮动的大小。

总之,基本思路就是对每一个中心点求最大的浮动范围,然后遍历所有基本中心点找出最大的。时间复杂度为O(N^2)。

3. 代码实现

  • 176 / 176 个通过测试用例
  • 状态:通过
  • 语言:Java
  • 执行用时: 29 ms 击败88%
  • 内存消耗: 38.2 MB 击败97%
public String longestPalindrome(String s) {
       int max=0;
        int temp;
        int pos=0;
        boolean flag=false;
        int length=s.length();
        for(int i=0;i<length;i++)
        {
            temp=0;
            for(int j=1;j<=i&&j+i<length;++j)
            {
                if(s.charAt(i-j)==s.charAt(i+j))
                    temp=j;
                else
                    break;
            }
            max=Math.max(max,temp);
            if(max==temp)
                pos=i;
        }
        for(int i=0;i<length-1;i++)
        {
            if(s.charAt(i)!=s.charAt(i+1))
                continue;
            temp=0;
            for(int j=1;j<=i&&i+j+1<length;++j)
            {
                if(s.charAt(i-j)==s.charAt(i+1+j))
                    temp=j;
                else
                    break;
            }
            max=Math.max(max,temp);
            if(max==temp)
            {
                flag=true;
                pos=i;
            }
        }
        if(!flag)
            return s.substring(pos-max,pos+max+1);
        return s.substring(pos-max,pos+max+2);
    }

总结

以上就是今天LeetCode寒假刷题day01所做的三道题。若有任何疑问,欢迎私信Call我鸭!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值