日常刷题
LeetCode #16 最接近的三数之和
链接:https://leetcode-cn.com/problems/3sum-closest/
昨天三数之和的变种,难度稍微增加了一点,暴力解了一遍,二分做了一遍。然后两遍都没有AC。
二分法只过了90%的数据,暴力解题毫无疑问的timeout。下面是代码
代码:
二分法:
class Solution: def threeSumClosest(self, nums, target): new_nums = 0 # 创建储存结果的变量 nums.sort() # 对原有数组进行排序处理 minaway = 100 for i in range(len(nums)-2): # 从小到大遍历所有的元素 left = i+1 # 创建左指针 right = len(nums)-1 # 创建右指针 while left < right: ident = nums[left] + nums[right] + nums[i] #将nums[i]加上最大的 和 最小的 数字 away = abs(ident - target) # 计算三数之和与target的距离 if away < minaway : # 判断距离是否为已知的最近距离 minaway = away # 对最小距离指针进行更新 new_nums = ident #对结果进行更新 if new_nums < target : left += 1 # 更新左指针 elif new_nums > target : right -= 1 #更新右指针 else : #当数据全部遍历完毕 return new_nums # 返回结果
暴力解法:
class Solution: def threeSumClosest(self, nums, target): minaway = 100000000000 away = 0 for i in range(len(nums)): for j in range(i+1,len(nums)): for k in range(j+1,len(nums)): if abs(nums[i]+nums[j]+nums[k]-target) < minaway: away = nums[i]+nums[j]+nums[k] minaway = abs(nums[i]+nums[j]+nums[k]-target) return away
LeetCode #26 删除排序数组中的重复项
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/description/
很水的写法,遍历n-1个元素,和后面一位比较,如果重复的话,remove nums[i].
代码:
class Solution: def removeDuplicates(self, nums): """ :type nums: List[int] pe: int """ i=0 while i<len(nums)-1: if nums[i]==nums[i+1]: nums.remove(nums[i]) else: i=i+1 return len(nums)
LeetCode #27 移除元素
链接:https://leetcode-cn.com/problems/remove-element/description/
很上面那道题类似,解法差不多,remove 即可
class Solution: def removeElement(self, nums, val): while val in nums: nums.remove(val) return len(nums)
LeetCode #31 下一个排序
链接:https://leetcode-cn.com/problems/next-permutation/description/
这道题 比较有意思。
第一次过了3/5的数据,没有考虑到最优解的情况。
代码如下:
class Solution: def nextPermutation(self, nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ i = len(nums)-1 while i>0: if nums[i] > nums[i-1]: t = nums[i-1] nums[i-1] = nums[i] nums[i] = t break i -= 1 else: nums = nums[::-1]
思路:
从后往前遍历,寻找升序子列表的断点。然后断点和升序子列表的第一位交换。
错误:
不是最优解。例如:1,3,2 。如果按照上面算法,得出的结果是3,1,2。而最优解是2,1,3。
改进的代码AC了。
如下:
class Solution: def nextPermutation(self, nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ i = len(nums) - 1 while i>0: if nums[i] <= nums[i-1]: # 从末至首寻找升序子列表 i -= 1 else : # 如果升序子列表中断,则跳出循环 break if i > 0: # 如果i>0,则证明num列表不全是升序元素 j = len(nums) - 1 while nums[j] <= nums[i-1] : # 从尾部开始找第一个比断点大的数字确保是最优解 j -= 1 nums[j],nums[i-1] = nums[i-1],nums[j] # 断点与该数字进行值的互换 new_list = sorted(nums[i:]) # 对断点之后进行升序排列,确保数字最小 k = 0 for m in range(i, len(nums)): nums[m] = new_list[k] k += 1 else : nums.sort()
思路:
从后往前找升序子列表(如 :1,3,2,1),寻找断点1(如1,3,2,1)。再从尾部开始找第一个比断点大的数字并于断点1进行交换(1,3,2,1)>>(2,3,1,1),然后再从断点开始进行从头至尾的升序排序(2,1,1,3),确保数字最小即最优解。