LintCode 1886: Moving Target (双指针题)

本文介绍了一种算法,用于将数组中指定目标元素移至数组前端,同时保持其余元素顺序不变。通过双指针技巧,该算法可在原地修改数组,避免额外内存消耗,适用于大量数据处理场景。

1886. Moving Target

 

Given an array nums and an integer target ,

you need to move the element which equal to target to the front of the array, and the order of the remain elements can not be changed.

You must do this moving in-place without making a copy of the array.

 

Example

Example 1:

Input:

nums = [5, 1, 6, 1]

target=1

Output: [1, 1, 5, 6]

Explanation: 1 is target, so you should keep them in the front of array

Example 2:

Input:

nums = [-1, 2, 3, 5, 2, 2]

target = 2

Output: [2, 2, 2, -1, 3, 5]

Explanation: 2 is target, so you should keep them in front of the array 

Example 3:

Input:

nums = [2, 3, 4, 6]

target = 1

Output: [2, 3, 4, 6]

Explanation: there is not target

Notice

The length of array is within range: [1, 100000]

if not appear target, you needn't do any change in place.

解法1:

把所有的非target元素都移到最右端,然后在最左端补上所有的target。

class Solution {
public:
    /**
     * @param nums: a list of integer
     * @param target: an integer
     * @return: nothing
     */
    void MoveTarget(vector<int> &nums, int target) {
        int n = nums.size();
        int targetCount = 0;
        int pLeft = n - 1, pRight = n - 1;

        for (int i = 0; i < n; ++i) {
            if (nums[i] == target) targetCount++;
        }
        
        if (targetCount == 0) return;
        
        while(pLeft >= 0) {
            if (nums[pLeft] != target) {
                nums[pRight] = nums[pLeft];
                pRight--;
            }
            pLeft--;
        }
        
        for (int i = 0; i < targetCount; ++i) {
            nums[i] = target;
        }
        return;
    }
};

另一种写法是把前2个循环搞到一起,但这样就不能先得到targetCount了。如果target==0,我们是不需要做任何事情的。

class Solution {
public:
    /**
     * @param nums: a list of integer
     * @param target: an integer
     * @return: nothing
     */
    void MoveTarget(vector<int> &nums, int target) {
        int n = nums.size();
        int targetCount = 0;
        int pLeft = n - 1, pRight = n - 1;
        while(pLeft >= 0) {
            if (nums[pLeft] != target) {
                nums[pRight] = nums[pLeft];
                pRight--;
            } else {
                targetCount++;
            }
            pLeft--;
        }
        
        for (int i = 0; i < targetCount; ++i) {
            nums[i] = target;
        }
        return;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值