1. 将一个数组分成左右两部分,使得右边的某个连续子段和减去左边的某个连续字段和最小[7,8,9,|3,5,-1] sum right - sum left minimal
想到左右分一刀,O(n),然后对左右分别取最大字段和算法,这样是O(n^2)。但是其实左右各扫一遍,然后记录下来就行了。
int minimaldif(vector<int> &a){ vector<int> max(a.size()); int sum = max[0] = a[0]; for (int i = 1; i < a.size(); i++) { if (sum < 0) sum = 0; sum = sum + a[i]; if (sum > max[i-1]) max[i] = sum; else max[i] = max[i-1]; } // min 数组(略) int result = a[a.size() - 1] - a[0]; // i is the start of right section for (int i = 1; i < a.size(); i++) { int maxVal = max[i]; int minVal = min[i]; if (minVal - maxVal < result) { result = minVal - maxVal; } } return result; }
2. 有若干0和1组成的等长字符串,求所有字符串相互的海明距离之和。
比如:“001000” “110000” “010111”
ham("001000","110000") = 3
ham("001000","010111") = 5
ham(“110000”,“010111”) = "4
那么结果为12
这道题的关键在于各个位之间其实没有关系,如果字符串长度为1,比如4个“1”和2个“0”,那么结果就是4*2==8。n位的就是把n位的结果相加就行了。
int sumofHamdistance(vector<string> &a) { int result = 0; int len = a[0].length(); for (int i = 0; i < len; i++) { int count1 = 0; int count0 = 0; for (int j = 0; j < a.size(); j++) { if (a[j][i] == '0') count0++; else if (a[j][i] == '1') count1++; } result += count1 * count0; } return result; }
3. 有两个整数x和y,问这两个整数是否有相同的质因数。比如:
samePrimefactor(68 ,17) = false 68 = 2 * 2 * 17 17 = 17
samePrimefactor(136, 578) = true 136 = 2 * 2 * 2 * 17, 578 = 2 * 17 * 17
这道题可以用GCD来做,还需要研究一下。
int gcd(int x,int y) { return y?gcd(y, x % y):x; } bool can(int a,int g) { while (g > 1) { if (g % a == 0) { return true; } g = gcd(g, a); a /= g; } return (a == 1); } int solution(vector<int> &A, vector<int> &B) { // write your code in C++98 int n = A.size(), result = 0; for (int i = 0; i < n; ++i) { int g = gcd(A[i], B[i]); if (can(A[i] / g, g) && can(B[i] / g, g)) { ++result; } } return result; }
发现的缺点一是括号的风格不一致,二是边界条件老是弄错,差个一。