Array[0] 利用i,j简化代码

1. Remove Element

走一遍A[],把符合要求的元素写到j

class Solution {
public:
    int removeElement(int A[], int n, int elem) {
        int j = -1;
        for (int i=0; i<n; ++i) {
            if (A[i] != elem)
                A[++j] = A[i];
        }
        return j+1;
    }
};

2. Remove Duplicates From Sorted Array

走一遍A[],把符合要求的元素写到j。这题要求后一个元素和前一个元素不同,那么我们在向A[j]写的时候就注意写入的元素是不是与A[j]相同

class Solution {
public:
    int removeDuplicates(int A[], int n) {
        if (n == 0) return 0;  //pay attention to the bound
        int j = 0;
        for(int i=1; i<n; ++i) {
            if (A[i] != A[j])
                A[++j] = A[i];
        }
        return j+1;
    }
};

3. Remove Duplicates From Sorted Array II

走一遍A[],把符合要求的元素写到j。此题要求最多有两个重复,也就是A[j-2] != A[j]

class Solution {
public:
    int removeDuplicates(int A[], int n) {
        if (n <= 2) return n;
        int j = 1;
        for(int i=2; i<n; ++i) {
            if (A[i] != A[j-1])
                A[++j] = A[i];
        }
        return j+1;
    }
};


5. Merge Sorted Array

同样的思路,用k来记录将要写的位置,注意in place地去做(题目说了,A[]空间足够)

class Solution {
public:
    void merge(int A[], int m, int B[], int n) {
        int k = m+n-1, i, j;
        for (i=m-1, j=n-1; i>=0 && j>=0;) {
            if (A[i] > B[j]) {
                A[k] = A[i]; --i;
            }
            else {
                A[k] = B[j]; --j;
            }
            --k;
        }
        while (j >= 0) {  //如果B剩下了就写,A剩下的肯定在头了,所以不用问
            A[j] = B[j];
            --j;
        }
    }
};

4. Sort Colors

这个题目如果可以two pass, 外加两个int count0, count1; 是非常容易实现的方法。

如果只允许one pass,该怎么办呢?

这里有个方法,用index0, index2分别代表应该写入0和2的index。每次A[i]都有3种可能的情况:0,1,2。遇到0我们就和应该swap(A[i], A[index0]); 遇到1,跳过;遇到2,swap(A[i], A[index2])。这样一来,i经过的位置目前已经为0或1了。此外i走的速度一定>=index0的速度,index0之前全是0,i走过的0都跑到index0之前了,所以算法可行。

分析时间复杂度:不要被if(A[i] == 2) ...i不动;吓到,以为是2 pass的走法,其实while(i<=index2)代表着i最多走到index2,而index2又反应着2的数目,正好补齐了A[i] == 2时i不动的窘境。还是很tricky的,不知道大家还有很好的one pass的想法吗?

class Solution {
public:
	void sortColors(int A[], int n) {
		int index0 = 0;
		int index2 = n - 1;
		int i = 0;
		while (i <= index2) {  //i走过的地方不是0就是1,把i遇到的0写到index0就可以避免1在0前面出现了
			if (A[i] == 0) { //我们知道交换到前面来的是0
				swap(A[i], A[index0]);
				index0++;
				i++;
			}
			else if (A[i] == 2) { //我们不知道交换到前面来的是0, 1, 2 ?所以i不能动
				swap(A[i], A[index2]);
				index2--;
			}
			else
				i++;
		}
	}
};

如果你有更清晰,更简洁的代码表达,欢迎讨论!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值