标签:判断 twosum 删除 字典顺序 假设 block 运动 编写 tno
不积跬步,无以至千里;不积小流,无以成江海。
内容主要是个人学习使用,题目分类以及部分参考资料来自于CyC的博客,非常感谢大佬,题目来源于LeetCode,非常感谢本站支持。
给定一个已按照升序排列的有序数组,找到两个数使得它们相加之和等于目标数。函数应该返回这两个下标值 index1 和 index2,其中 index1?必须小于?index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
解题思路:
本题是1. 两数之和的升级版本,题意给定的是一个升序排列的有序数组,利用双指针
,指针1指向值较小的元素,指针2指向值较大的元素。指针1从头向尾遍历,指针2从尾向头遍历。
sum>target
,即需要减小某个元素,所以将指针2向左移动,指针1不动(之所以不把指针1向左移动是促使两个指针相遇,终止条件)sum<target
,即需要增大某个元素,所以将指针1向右移动,指针2不动sum==target
,且指针1和指针2不指向同一个元素代码实现:
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
left = 0
right = len(numbers)-1
while left<right: # 判断指针是否相遇
num = numbers[left] + numbers[right]
if num>target:
right-=1 # 指针2左移
elif num<target:
left+=1 # 指针1右移
else:
# 下标加一返回位置
left+=1
right+=1
return [left,right]
给定一个非负整数?c?,你要判断是否存在两个整数 a 和 b,使得?a2 + b2 = c。
示例1:
输入: 5
输出: True
解释: 1 * 1 + 2 * 2 = 5
示例2:
输入: 3
输出: False
解题思路:
本题其实是上一题的变形,target等于两个数的平方和,题目核心条件:
0-√target
,因为a2+b2=target,极端情况是a=0,b=√target,所以当a不断增大,b一定需要小于√target0-√target
可以看作是一组有序的数组[0,1,2,3,4,5,6...]代码实现:
class Solution:
def judgeSquareSum(self, c: int) -> bool:
left = 0
right = int(c**0.5) # 相当于√target
while left<=right: # 指针可以相遇,例如:1*1+1*1=2,即left指向1,right指向1
num = left*left+right*right
if num>c:
right-=1 # 指针2左移
elif num<c:
left+=1 # 指针1右移
else:
return True
return False
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
示例 1:
输入: "hello"
输出: "holle"
示例 2:
输入: "leetcode"
输出: "leotcede"
说明:
元音字母不包含字母"y"。
解题思路:
{"a","e","i","o","u",‘A‘, ‘E‘, ‘I‘, ‘O‘, ‘U‘}
,采用集合存储时间复杂度优于列表,Python底层采用的是hash。代码实现:
class Solution:
def reverseVowels(self, s: str) -> str:
words = {"a", "e", "i", "o", "u", ‘A‘, ‘E‘, ‘I‘, ‘O‘, ‘U‘}
l = list(s) # 拆分列表用于交换元素
left = 0
right = len(l) - 1
while left < right:
if l[left] in words and l[right] in words: # 指针1,2都指向元音
l[left], l[right] = l[right], l[left]
left += 1
right -= 1
elif l[left] not in words: # 指针1没有指向元音,指针2指向元音
left += 1
elif l[right] not in words: # 指针2没有指向元音,指针1指向元音
right -= 1
return "".join(l)
给定一个非空字符串?s,最多删除一个字符。判断是否能成为回文字符串。
示例 1:
输入: "aba"
输出: True
示例 2:
输入: "abca"
输出: True
解释: 你可以删除c字符。
注意:
字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。
解题思路:
本题是9. 回文数的升级版,即给回文字符串一次机会,注意这个机会存在两种情况,具体情况如下:
官方说明:贪心算法,即当左右指针相等,此时验证就是去头去尾后的字符串,保证它为回文,则整个字符串就是回文,依次递减。
代码实现:
class Solution:
def validPalindrome(self, s: str) -> bool:
left = 0
right = len(s) - 1
while left < right:
if s[left] == s[right]:
left += 1
right -= 1
else:
return self.compare(s, left + 1, right) or self.compare(s, left, right - 1) # 删除一个元素,左边或右边,剩余的检查是否为回文字符串
return True
def compare(self, s, left, right):
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
给你两个有序整数数组?nums1 和 nums2,请你将 nums2 合并到?nums1?中,使 nums1 成为一个有序数组。
说明:
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出:?[1,2,2,3,5,6]
解题思路:
当时看到这个题还是有点懵逼,主要是利用num1,由题意可知nums1有足够空间,采用双指针如下:
代码实现:
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
p1 = m - 1
p2 = n - 1
k = m + n - 1
while p1 >= 0 and p2 >= 0:
if nums1[p1] > nums2[p2]:
nums1[k] = nums1[p1] # nums1>nums2,将nums1当前元素添加在末尾
p1 -= 1
else:
nums1[k] = nums2[p2] # nums2>nums1,将nums2当前元素添加在末尾
p2 -= 1
k -= 1 # 每添加一个末尾游标减一
nums1[:p2+1] = nums2[:p2+1] # 将剩余的nums2元素添加在nums对应位置(一般为头部)
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
解题思路:
这个题目用了一个很巧妙的方法,就像是脑筋急转弯,主要利用双指针+快慢指针
:
代码实现:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if(head == None or head.next == None):
return False
slow = head # 慢指针
quick = head.next # 快指针
while quick != None and quick.next != None: # 判断当前快指针和快指针下一个(防止溢出)是否走到链表尾部
if quick == slow: # 快慢相遇
return True
slow = slow.next # 慢指针指向下一个
quick = quick.next.next # 快指针指向下下个
return False
给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。
示例 1:
输入:
s = "abpcplea", d = ["ale","apple","monkey","plea"]
输出:
"apple"
题意:
解题思路:
代码实现:
class Solution:
def findLongestWord(self, s: str, d: List[str]) -> str:
d.sort(key=lambda x: [-len(x), x]) # 排序,规则:长的靠前,相同长度按照字典顺序
for item in d:
i = 0
j = 0
while i < len(item) and j < len(s): # 判断某一个串是否到达结尾
if item[i] == s[j]: # 相同,子串指针加一
i += 1
j += 1 # 主串指针始终加一
if len(item) == i: # 找到子串,由于已经是有序的即直接返回
return item
return ""
标签:判断 twosum 删除 字典顺序 假设 block 运动 编写 tno
原文地址:https://www.cnblogs.com/ydongy/p/13090421.html