文章目录
前言
之前报名了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我鸭!