1. 两数之和
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
1 class Solution: 2 def twoSum(self, nums: List[int], target: int) -> List[int]: 3 nums_len = len(nums) 4 nums_copy = list() 5 6 for index in range(nums_len): 7 nums_copy.append([nums[index],index]) 8 9 nums_copy.sort(key=lambda x: x[0]) 10 front_point, back_point = 0, nums_len - 1 11 12 while front_point < back_point: 13 if nums_copy[front_point][0] + nums_copy[back_point][0] > target: 14 back_point -= 1 15 elif nums_copy[front_point][0] + nums_copy[back_point][0] < target: 16 front_point += 1 17 else: 18 return [nums_copy[front_point][1], nums_copy[back_point][1]] 19 return []
11. 盛最多水的容器
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入:[1,8,6,2,5,4,8,3,7] 输出:49
1 class Solution: 2 def maxArea(self, height: List[int]) -> int: 3 front_point, back_point = 0, len(height) - 1 4 max_area = 0 5 6 while back_point > front_point: 7 min_height = min(height[front_point], height[back_point]) 8 temp_max_area = min_height *(back_point - front_point) 9 10 if temp_max_area > max_area: 11 max_area = temp_max_area 12 if height[front_point] == min_height: 13 front_point += 1 14 else: 15 back_point -= 1 16 17 return max_area
15. 三数之和
给你一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
1 class Solution: 2 def threeSum(self, nums: List[int]) -> List[List[int]]: 3 if not nums: 4 return [] 5 6 nums_size = len(nums) 7 if nums_size <= 1: 8 return [] 9 10 nums.sort() 11 12 res = [] 13 14 for index in range(nums_size-2): 15 if nums[index] > 0: 16 break 17 if index > 0 and nums[index] == nums[index - 1]: 18 continue 19 front_point, back_point = index + 1, nums_size - 1 20 21 while front_point < back_point: 22 sum_3_nums = nums[index] + nums[front_point] + nums[back_point] 23 if sum_3_nums < 0: 24 front_point += 1 25 while front_point < back_point and nums[front_point - 1] == nums[front_point]: 26 front_point += 1 27 elif sum_3_nums > 0: 28 back_point -= 1 29 while front_point < back_point and nums[back_point + 1] == nums[back_point]: 30 back_point -= 1 31 else: 32 temp = [nums[index], nums[front_point], nums[back_point]] 33 res.append(temp[:]) 34 front_point += 1 35 back_point -= 1 36 while front_point < back_point and nums[front_point - 1] == nums[front_point]: 37 front_point += 1 38 while front_point < back_point and nums[back_point + 1] == nums[back_point]: 39 back_point -= 1 40 41 return res
16. 最接近的三数之和
给定一个包括 n 个整数的数组 nums
和 一个目标值 target
。找出 nums
中的三个整数,使得它们的和与 target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
1 class Solution: 2 def threeSumClosest(self, nums: List[int], target: int) -> int: 3 if not nums: 4 return None 5 nums_size = len(nums) 6 7 if nums_size <= 1: 8 return None 9 10 nums.sort() 11 min_difference = float("inf") 12 13 for index in range(nums_size - 2): 14 15 #去重 16 if index > 0 and nums[index - 1] == nums[index]: 17 continue 18 19 front_point, back_point = index + 1, nums_size - 1 20 21 while front_point < back_point: 22 sums_3_nums = nums[index] + nums[front_point] + nums[back_point] 23 difference = sums_3_nums - target 24 if abs(difference) < abs(min_difference): 25 min_difference = difference 26 27 if difference < 0: 28 front_point += 1 29 #去重 30 while front_point < back_point and nums[front_point] == nums[front_point - 1]: 31 front_point += 1 32 elif difference > 0: 33 back_point -= 1 34 #去重 35 while front_point < back_point and nums[back_point] == nums[back_point + 1]: 36 back_point -= 1 37 else: 38 return target 39 40 return target + min_difference
18. 四数之和
给定一个包含 n 个整数的数组 nums
和一个目标值 target
,判断 nums
中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target
相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
1 class Solution: 2 def fourSum(self, nums: List[int], target: int) -> List[List[int]]: 3 if not nums: 4 return [] 5 6 nums_size = len(nums) 7 if nums_size <= 3: 8 return [] 9 10 nums.sort() 11 print(nums) 12 res = [] 13 14 for index in range(nums_size - 3): 15 16 if nums[index] > target //4: 17 break 18 19 if index > 0 and nums[index] == nums[index - 1]: 20 continue 21 22 for j_index in range(index + 1, nums_size-2): 23 if j_index > index + 1 and nums[j_index] == nums[j_index - 1]: 24 continue 25 26 front_point, back_point = j_index + 1, nums_size - 1 27 28 while front_point < back_point: 29 sum_4_nums = nums[index] + nums[j_index] + nums[front_point] + nums[back_point] 30 diffirence = sum_4_nums - target 31 if diffirence < 0: 32 front_point += 1 33 while front_point < back_point and nums[front_point - 1] == nums[front_point]: 34 front_point += 1 35 elif diffirence > 0: 36 back_point -= 1 37 while front_point < back_point and nums[back_point + 1] == nums[back_point]: 38 back_point -= 1 39 else: 40 temp = [nums[index], nums[j_index], nums[front_point], nums[back_point]] 41 res.append(temp[:]) 42 front_point += 1 43 back_point -= 1 44 while front_point < back_point and nums[front_point - 1] == nums[front_point]: 45 front_point += 1 46 while front_point < back_point and nums[back_point + 1] == nums[back_point]: 47 back_point -= 1 48 49 return res
19. 删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: 9 slow_point, fast_point = head, head 10 11 for _ in range(n): 12 fast_point = fast_point.next 13 14 if not fast_point: 15 return head.next 16 17 while fast_point.next: 18 slow_point = slow_point.next 19 fast_point = fast_point.next 20 21 slow_point.next = slow_point.next.next 22 23 return head
26. 删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为1
,2
。 你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4], 函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为0
,1
,2
,3
,4
。 你不需要考虑数组中超出新长度后面的元素。
1 class Solution: 2 def removeDuplicates(self, nums: List[int]) -> int: 3 if not nums: 4 return 0 5 6 nums_size = len(nums) 7 if nums_size == 1: 8 return 1 9 10 slow_point, fast_point = 1, 1 11 12 for fast_point in range(1, nums_size): 13 if nums[fast_point] != nums[fast_point - 1]: 14 nums[slow_point] = nums[fast_point] 15 slow_point += 1 16 else: 17 continue 18 19 return slow_point
27. 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度5
, 并且 nums 中的前五个元素为0
,1
,3
,0
, 4。 注意这五个元素可为任意顺序。 你不需要考虑数组中超出新长度后面的元素。
1 class Solution: 2 def removeElement(self, nums: List[int], val: int) -> int: 3 if not nums: 4 return 0 5 6 slow_point, fast_point = 0, 0 7 8 for fast_point in range(len(nums)): 9 if nums[fast_point] != val: 10 nums[slow_point] = nums[fast_point] 11 slow_point += 1 12 13 return slow_point
28. 实现 strStr()
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll" 输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba" 输出: -1
1 class Solution: 2 def strStr(self, haystack: str, needle: str) -> int: 3 if not needle: 4 return 0 5 6 haystack_size, needle_size = len(haystack), len(needle) 7 slow_point = 0 8 9 while slow_point <= haystack_size - needle_size: 10 if haystack[slow_point: slow_point + needle_size] == needle: 11 return slow_point 12 slow_point += 1 13 14 return -1
61. 旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2 输出: 4->5->1->2->3->NULL 解释: 向右旋转 1 步: 5->1->2->3->4->NULL 向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:
输入: 0->1->2->NULL, k = 4 输出:2->0->1->NULL
解释: 向右旋转 1 步: 2->0->1->NULL 向右旋转 2 步: 1->2->0->NULL 向右旋转 3 步:0->1->2->NULL
向右旋转 4 步:2->0->1->NULL
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 def rotateRight(self, head: ListNode, k: int) -> ListNode: 9 if not head: 10 return None 11 if not head.next: 12 return head 13 fast_point, slow_point = head, head 14 length = self.lengthList(head) 15 16 #k大于等于链表长度 17 if k >= length: 18 for _ in range(k%length): 19 front_point, back_point = head, head.next 20 while back_point.next: 21 back_point = back_point.next 22 front_point = front_point.next 23 back_point.next = head 24 front_point.next = None 25 head = back_point 26 return head 27 28 #k小于链表长度 29 for _ in range(k): 30 if fast_point: 31 fast_point = fast_point.next 32 else: 33 break 34 35 while fast_point.next: 36 slow_point = slow_point.next 37 fast_point = fast_point.next 38 fast_point.next = head 39 head = slow_point.next 40 slow_point.next = None 41 42 return head 43 44 def lengthList(self, head: ListNode) -> int: 45 temp = head 46 length = 0 47 while temp: 48 length += 1 49 temp = temp.next 50 51 return length
80. 删除排序数组中的重复项 II
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定 nums = [1,1,1,2,2,3], 函数应返回新长度 length =5
, 并且原数组的前五个元素被修改为1, 1, 2, 2,
3 。 你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,1,2,3,3], 函数应返回新长度 length =7
, 并且原数组的前五个元素被修改为0
, 0, 1, 1, 2, 3, 3 。 你不需要考虑数组中超出新长度后面的元素。
1 class Solution: 2 def removeDuplicates(self, nums: List[int]) -> int: 3 if not nums: 4 return 0 5 6 nums_size = len(nums) 7 if nums_size == 1: 8 return 1 9 10 slow_point, fast_point = 0, 0 11 12 for fast_point in range(0, nums_size): 13 if fast_point == 0 or (fast_point > 0 and nums[fast_point] != nums[fast_point - 1]): 14 temp_num_time = 1 15 nums[slow_point] = nums[fast_point] 16 slow_point += 1 17 elif temp_num_time == 1: 18 temp_num_time += 1 19 nums[slow_point] = nums[fast_point] 20 slow_point += 1 21 else: 22 continue 23 24 return slow_point
86. 分隔链表
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
示例:
输入: head = 1->4->3->2->5->2, x = 3 输出: 1->2->2->4->3->5
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 def partition(self, head: ListNode, x: int) -> ListNode: 9 if not head: 10 return None 11 smallerNode = ListNode(0) 12 biggerNode = ListNode(x) 13 14 smaller_pointer, bigger_pointer = smallerNode, biggerNode 15 pointer = head 16 while pointer: 17 if pointer.val < x: 18 smaller_pointer.next = pointer 19 smaller_pointer = smaller_pointer.next 20 pointer = pointer.next 21 smaller_pointer.next = None 22 else: 23 bigger_pointer.next = pointer 24 bigger_pointer = bigger_pointer.next 25 pointer = pointer.next 26 bigger_pointer.next = None 27 28 smaller_pointer.next = biggerNode.next 29 30 return smallerNode.next
88. 合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 num1 成为一个有序数组。
说明:
- 初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
- 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 输出: [1,2,2,3,5,6]
1 class Solution: 2 def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: 3 """ 4 Do not return anything, modify nums1 in-place instead. 5 """ 6 if m + n == 0: 7 return 8 9 slow_pointer = m + n - 1 10 nums1_pointer = m - 1 11 nums2_pointer = n - 1 12 13 while nums1_pointer >= 0 and nums2_pointer >= 0: 14 if nums1[nums1_pointer] >= nums2[nums2_pointer]: 15 nums1[slow_pointer] = nums1[nums1_pointer] 16 nums1_pointer = nums1_pointer - 1 17 slow_pointer = slow_pointer - 1 18 else: 19 nums1[slow_pointer] = nums2[nums2_pointer] 20 nums2_pointer = nums2_pointer - 1 21 slow_pointer = slow_pointer - 1 22 23 while nums1_pointer >= 0: 24 nums1[slow_pointer] = nums1[nums1_pointer] 25 nums1_pointer = nums1_pointer - 1 26 slow_pointer = slow_pointer - 1 27 28 while nums2_pointer >= 0: 29 nums1[slow_pointer] = nums2[nums2_pointer] 30 nums2_pointer = nums2_pointer - 1 31 slow_pointer = slow_pointer - 1 32 33 return
125. 验证回文串
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama" 输出: true
示例 2:
输入: "race a car" 输出: false
1 class Solution: 2 def isPalindrome(self, s: str) -> bool: 3 if not s: 4 return True 5 front_pointer, back_pointer = 0, len(s) - 1 6 7 while front_pointer < back_pointer: 8 if s[front_pointer].isalnum() and s[back_pointer].isalnum(): 9 if s[front_pointer].lower() != s[back_pointer].lower(): 10 return False 11 else: 12 front_pointer += 1 13 back_pointer -= 1 14 elif (not s[front_pointer].isalnum()) and (not s[back_pointer].isalnum()): 15 front_pointer += 1 16 back_pointer -= 1 17 elif s[front_pointer].isalnum() and (not s[back_pointer].isalnum()): 18 back_pointer -= 1 19 else: 20 front_pointer += 1 21 22 return True
141. 环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos
是 -1
,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1], pos = -1 输出:false 解释:链表中没有环。
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 def hasCycle(self, head: ListNode) -> bool: 9 if not head: 10 return False 11 12 slow_pointer, fast_pointer = head, head 13 14 while fast_pointer.next: 15 slow_pointer = slow_pointer.next 16 fast_pointer = fast_pointer.next.next 17 if fast_pointer == slow_pointer: 18 return True 19 elif not fast_pointer: 20 break 21 22 return False
142. 环形链表 II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos
是 -1
,则在该链表中没有环。
说明:不允许修改给定的链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 def detectCycle(self, head: ListNode) -> ListNode: 9 if not head: 10 return None 11 12 slow_pointer, fast_pointer = head, head 13 14 while fast_pointer.next: 15 slow_pointer = slow_pointer.next 16 fast_pointer = fast_pointer.next.next 17 if fast_pointer == slow_pointer: 18 fast_pointer = head 19 while fast_pointer != slow_pointer: 20 fast_pointer = fast_pointer.next 21 slow_pointer = slow_pointer.next 22 return slow_pointer 23 elif not fast_pointer: 24 break 25 26 return None
NC128 容器盛水问题
链接:https://www.nowcoder.com/questionTerminal/f92929ec6e5642a690e7c197b0c40e38?orderByHotValue=1&mutiTagIds=1579&page=1&onlyReference=false
来源:牛客网
给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个容器,请返回容器能装多少水。
具体请参考样例解释
输入描述:
第一行一个整数N,表示数组长度。
接下来一行N个数表示数组内的数。
输出描述:
输出一个整数表示能装多少水。
6
3 1 2 5 2 4
输出
5
说明
示例2
输入
5
4 5 1 3 2
输出
2
1 class Solution: 2 def maxWater(self , arr ): 3 # write code here 4 if not arr: 5 return 0 6 left, right = 0, len(arr)-1 7 left_val, right_val = arr[left], arr[right] 8 max_water = 0 9 while left < right: 10 if left_val < right_val: 11 left += 1 12 if arr[left] >= left_val: 13 left_val = arr[left] 14 continue 15 else: 16 max_water += (left_val - arr[left]) 17 else: 18 right -= 1 19 if arr[right] >= right_val: 20 right_val = arr[right] 21 continue 22 else: 23 max_water += (right_val - arr[right]) 24 25 return max_water 26 27 28 S = Solution() 29 while True: 30 try: 31 arr = list(map(int, input()[1:-1].split(','))) 32 print(S.maxWater(arr)) 33 except: 34 break