LeetCode编程实践——腾讯精选50题 (一)
⋆ \star ⋆ 题号-2 ⋆ \star ⋆ 难度-中等
题目链接: https://leetcode-cn.com/problems/add-two-numbers/
题目:给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
做题准备:
- 链表介绍:链表 ( l i n k e d l i s t ) (linked list) (linkedlist) 是一种在物理上非连续、非顺序的数据结构,由若干节点 ( n o d e ) (node) (node) 所组成。
- 单向链表的每一个节点又包含两部分,一部分是存放数据的变量 d a t a data data ,另一部分是指向下一个节点的指针 n e x t next next 。
class Node:
def __init__(self,data);
self.data=data
self.next=None
- 链表的第一个节点被称为头节点,最后一个节点被称为尾节点,尾节点的 n e x t next next 指针指向空。
- 与数组按照下标来随机寻找元素不同,对于链表的其中一个节点 A A A ,我们只能根据节点A的 n e x t next next 指针来找到该节点的下一节点 B B B ,再根据节点 B B B 的 n e x t next next 指针找到下一个节点 C C C … …
- 如果想通过链表的一个节点回溯到他的前置节点,我们采用双向链表。双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有 d a t a data data 和 n e x t next next 指针,还拥有指向前置节点的 p r e v prev prev 指针。
- 总结:链表中的元素可存储在内存的任何地方。链表的每个元素都存储了下一个元素的地址,从而使一系列随机的内存地址串在一起。在链表中添加元素很容易:只需将其放入内存,并将其地址存储到前一个元素中。
题目实现(pycharm实现):
#!/usr/bin/python3
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
# 类似这样的需要生成新的listnode的题目使用哑结点会方便处理一些,
# 就是在前面多加一个任意结点,最后返回.next就可以
# 其实ans和head可以理解为指向同一个链表的指针,所以针对head的改动也可以体现在ans上
# ans用来输出最后的listnode,head用来处理遍历生成新的listnode
ans = head = ListNode(0)
digit = 0 # 标记进位情况
# 当l1与l2没有遍历完的时候,依次遍历相加,并将和加入到结果中
while l1 and l2:
num = l1.val + l2.val + digit # 计算l1和l2在该位数上的和
head.next = ListNode(num % 10) # 将两者的和取个位数添加到结果head和ans中
digit = num // 10 # 标记进位情况,有进位则为1,无进位为0
head, l1, l2 = head.next, l1.next, l2.next # 所有链表后移达到遍历效果
# 当l1较长时执行该循环
while l1:
num = l1.val + digit
head.next = ListNode(num % 10)
digit = num // 10
head, l1 = head.next, l1.next
# 当l2较长时执行该循环
while l2:
num = l2.val + digit
head.next = ListNode(num % 10)
digit = num // 10
head, l2 = head.next, l2.next
# l1和l2均遍历完毕,查看最高位是否还有进位,若有则加入
if digit:
head.next = ListNode(digit)
# 返回哑结点的next
return ans.next
def listToListnode(l):
head = temp = ListNode(0)
for num in l:
temp.next = ListNode(num)
temp = temp.next
temp.next = None
return head.next
def listnodeToList(head):
ans = []
while head:
ans.append(head.val)
head = head.next
return ans
if __name__ == '__main__':
l1 = [2, 4, 3]
l2 = [5, 6, 4]
l1 = listToListnode(l1)
l2 = listToListnode(l2)
so = Solution()
ans = so.addTwoNumbers(l1, l2)
ans = listnodeToList(ans)
print(ans)
⋆ 题号-4 ⋆ 难度-困难
题目链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
题目:给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。
题目实现:
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
m = len(nums1)
n = len(nums2)
nums1.extend(nums2)# 合并
nums1.sort()# 排序
if (m + n) & 1:# 如果是奇数 返回中位数
return nums1[(m + n - 1) >> 1]
else:# 返回两个中位数的平均值
return (nums1[(m + n - 1) >> 1] + nums1[(m + n) >> 1]) / 2
⋆ 题号-5 ⋆ 难度-中等
题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/
题目:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
题目实现:
class Solution:
def longestPalindrome(self, s: str) -> str:
count = len(s)
if count == 0 or count == 1:
return s
longestPalindromelen = 1
longestPalindromeStr = s[0:1]
dp = [[False] * count for i in range(count)]
for r in range(1, count):
for l in range(0, r):
if s[r] == s[l] and (r - l <= 2 or dp[l + 1][r - 1] == True):
dp[l][r] = True
if longestPalindromelen < r - l + 1:
longestPalindromelen = r - l + 1
longestPalindromeStr = s[l:l + longestPalindromelen]
return longestPalindromeStr