日常刷题

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),确保数字最小即最优解。