//ACM 1 数组 #include <stdio.h> #include "sort.h" int arrDump(int * a, int n) { int i = 0; printf("Array:["); for (i=0; i<n; i++) { printf(" %d ", a[i]); } printf("]\n"); return 0; } /* 删除有序数组中重复元素 时间 O(n) 空间 O(1) */ int removeSortedDup(int * a, int n, int * len) { int i = 0, index = 0; for (i=1; i<n; i++) { if (a[i] != a[index])//no duplicate { a[++index] = a[i];//resort } } *len = index+1; return 0; } /* 允许最多两次重复 时间 O(n) 空间 O(1) */ int removeSortedDupTwice(int * a, int n, int * len) { int i = 0, index = 0, sum = 1; for (i=1; i<n; i++) { if (a[i] != a[index])//no duplicate { a[++index] = a[i];//resort sum = 1; } else if (sum <2) { a[++index] = a[i]; sum ++; } } *len = index+1; return 0; } /*网上的代码*/ int removeDuplicates(int A[], int n) { int index = 2, i=2; if (n <= 2) return n; for (i = 2; i < n; i++){ if (A[i] != A[index - 2])//窗口 index-2, index-1 A[index++] = A[i]; //操作后A[index]始终与之前元素不同 } return index; } /* 二分查找 */ int BinarySearch(int a[], int len, int target) { int left = 0, right = len-1, mid = 0; while (left <= right) { mid = (left+right) / 2; if (target == a[mid]) { return mid; } else if(target < a[mid]) { right = mid - 1; } else { left = mid + 1; } } return -1; } /* 有序数组从中间折断,前后两部分换位 Search in Rotated Sorted Array 难度在于二分边界的确定 不使用直接查找,使用二分查找 时间 O(log n) 空间 O(1) */ int RotateSearch(int a[], int len, int target) { int left = 0, right = len-1, mid = 0; while (left <= right) { mid = (left+right) / 2; if (a[mid] == target) return mid; if (a[mid] < a[left])//同a[mid] > a[right],因为此时 a[left]>a[right] { if (target>a[mid] && target<=a[right]) left = mid + 1; else right = mid - 1; } else// if (a[mid] >= a[left]) { if (target>=a[left] && target<a[mid])//同target>=a[left] && target<=a[mid] right = mid - 1; else left = mid + 1; } } return -1; } //同上,调用之前的二分查找实现 //int RotateSearch(int a[], int len, int target) //{ // int left = 0, right = len-1, mid = 0; // while (left < right) // { // mid = (left+right) / 2; // if (a[mid] < a[left])//同a[mid] > a[right],因为此时 a[left]>a[right] // { // right = mid; // } // else if (a[mid] > a[right]) // { // left = mid; // } // if (left == right-1) // { // mid = a[left]>a[right] ? left : right; // break;//pivot = mid // } // } // printf("Pivot index: %d\n", mid); // if (a[mid] == target) // { // return mid; // } // else if (target > a[0]) // { // return BinarySearch(a, mid+1, target); // } // else // { // return (mid+1 + BinarySearch(&a[mid+1], len-mid, target)); // } //} /* Search in Rotated Sorted Array 允许重复元素,查找数组中是否存在target 注意特殊情况:数组有序但不连续 */ int RotateSearchDup(int a[], int len, int target) { int left = 0, right = len-1, mid = 0, tmp = -1; while (left <= right) { mid = (left+right) / 2; if (a[mid] == target) return mid; else if (right-left <= 1) { return -1; } if (a[mid] > a[left])//同a[mid] > a[right],因为此时 a[left]>a[right] { if (target>=a[left] && target<a[mid])//同target>=a[left] && target<=a[mid] right = mid - 1; else left = mid + 1; } else if (a[mid] < a[right]) { if (target>a[mid] && target<=a[right]) left = mid + 1; else right = mid - 1; } else if (a[mid] == a[left])//special situation { if (target > a[mid]) { tmp = RotateSearchDup(&a[left], mid-left+1, target); if (tmp != -1) return left+tmp; tmp = RotateSearchDup(&a[mid+1], right-mid, target); if (tmp != -1) return mid+1+tmp; } else left = mid+1; } else if (a[mid] == a[right]) { if (target > a[mid]) { tmp = RotateSearchDup(&a[mid], right-mid+1, target); if (tmp != -1) return mid+tmp; tmp = RotateSearchDup(&a[left], mid-left, target); if (tmp != -1) return left+tmp; } else right = mid-1; } } return -1; }
某ACM网站上看到的题目,原题是英文的,今天一回头又找不着了……
时间: 2024-11-03 05:37:31