【20200326】【每天一道算法题】移动零(数组)

问题

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12],输出: [1,3,12,0,0]

说明:

必须在原数组上操作,不能拷贝额外的数组。

尽量减少操作次数。


思路及代码

# 方法一:类似于冒泡排序法的冒泡思想
# 思路:循环次数为len(nums)-1,如果遇到0,那么交换比较的这两个相邻元素;否则直接后移指针即可。
# 时间复杂度:O(n^2)
# 空间复杂度:O(1)
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        l = len(nums)
       
        while l:   # 控制循环次数
            i, j = 0, 1
            while j < l:
                if nums[i] == 0 and nums[j] != 0:
                    nums[i], nums[j] = nums[j], nums[i]
                i += 1
                j += 1                    
            l -= 1
			
			
# 方法二:双指针、快慢指针(局部最优,需要写零很多次,执行很多次写操作)
# 思路:定义两个指针,一快一慢,快指针用于判断该元素是否为0,慢指针用于存放非0元素,即如果快指针元素非零,那么放在慢指针的位置并且快、慢指针都加一;否则慢指针不动,快指针加一。
# 时间复杂度:O(n)
# 空间复杂度:O(1)
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        slow = 0
        for fast in range(0, len(nums)):   # 这个for循环是关键
            if nums[fast] != 0:
                nums[slow] = nums[fast]
                slow += 1
				
        for idx in range(slow, len(nums)):   # 补齐后面的0
            nums[idx] = 0
			
			
# 方法三:最优操作
# 思路:和方法二很像,要求慢指针之前的元素全为非0,慢指针和快指针之间的元素都为0,这个方法不是最后才补齐0,而是交换零元素和非零元素。
# 时间复杂度:O(n)
# 空间复杂度:O(1)
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        slow = 0
        for fast in range(0, len(nums)):
            if nums[fast] == 0:
                fast = fast + 1
            else:
                nums[slow], nums[fast] = nums[fast], nums[slow]
                slow, fast = slow + 1, fast + 1

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这道可以使用二分查找算法来解决。我们需要将两个数组合并成一个有序的数组,然后找到这个有序数组的中位数。具体步骤如下: 1. 定义两个指针 i 和 j,分别指向 nums1 和 nums2 的起始位置。 2. 使用二分查找算法查找有序数组中的中位数。我们需要将查找的范围缩小到两个数组的中间位置左右。 3. 如果 nums1[i] < nums2[j],说明中位数在 nums1[i] 和 nums2[j] 之间。我们将 i 向右移动一位,缩小查找范围。 4. 如果 nums1[i] >= nums2[j],说明中位数在 nums1[i] 和 nums2[j] 之间。我们将 j 向右移动一位,缩小查找范围。 5. 重复步骤 2 到 4,直到找到中位数。 Java 代码实现如下: ```java public double findMedianSortedArrays(int[] nums1, int[] nums2) { int m = nums1.length; int n = nums2.length; if (m > n) { // 保证 nums1 的长度小于等于 nums2 的长度 int[] temp = nums1; nums1 = nums2; nums2 = temp; int tmp = m; m = n; n = tmp; } int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2; while (iMin <= iMax) { int i = (iMin + iMax) / 2; int j = halfLen - i; if (i < iMax && nums2[j-1] > nums1[i]){ iMin = i + 1; // i is too small } else if (i > iMin && nums1[i-1] > nums2[j]) { iMax = i - 1; // i is too big } else { // i is perfect int maxLeft = 0; if (i == 0) { maxLeft = nums2[j-1]; } else if (j == 0) { maxLeft = nums1[i-1]; } else { maxLeft = Math.max(nums1[i-1], nums2[j-1]); } if ( (m + n) % 2 == 1 ) { return maxLeft; } int minRight = 0; if (i == m) { minRight = nums2[j]; } else if (j == n) { minRight = nums1[i]; } else { minRight = Math.min(nums2[j], nums1[i]); } return (maxLeft + minRight) / 2.0; } } return 0.0; } ``` 时间复杂度为 O(log(min(m, n)))。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Satisfying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值