1. 数组中的重复数字
- 解法一:将数组排序,快排,排序一个长度为n的数组需要O(nlogn)的时间。
- 解法二:利用HashMap,记录每个数字出现次数,第一个大于2的即可返回。时间复制度为O(n),需要大小为O(n)的哈希表为代价。
- 解法三:其实也是一种通用思想,题目条件中有“一个长度为n的数组里,所有数字都在[0,n-1]”。那么我们可以不开辟新的存储空间,就可以在O(n)时间复杂度里完成本题。即从头遍历,目的是让每个位置都存其对应的数值,比如a[0]存0,a[3]存3。
public class Duplicate {
public static boolean dup(int number[], int length, int[] duplication) {
if (number == null || length <= 0) return false;
for (int i = 0; i < length; i++) {
if (number[i] < 0 || number[i] > length - 1) return false;
}
for (int i = 0; i < length - 1; i++) {
while (number[i] != i) {
if (number[i] == number[number[i]]) {
duplication[0] = number[i];
return true;
}
int temp = number[i];
number[i] = number[temp];
number[temp] = temp;
}
}
return false;
}
public static void main(String[] args) {
int[] number = {2, 3, 1, 0, 4, 5, 3};
int[] duplication = new int[1];
System.out.println(dup(number, number.length, duplication));
}
}
2. 二维数组中的查找
- 解法一:首先选取数组中右上角的数字。如果该数字等于要查找的数字,则查找结束,如果该数字大于要查找的数字,则剔除这个数字所在的列;如果该数字小于要查找的数字,则剔除这个数字的所在行。
- 解法二:二分查找法。
public class Find {
public static boolean findTo(int target, int[][] array) {
boolean flag = false;
int rows = array.length;
int columns = array[0].length;
if (array != null && rows > 0 && columns > 0) {
int row = 0;
int column = columns - 1;
while (row < rows && column >= 0){
if (array[row][column] == target){
flag = true;
break;
}
else if (array[row][column] > target){
column --;
}
else row ++;
}
}
return flag;
}
public static void main(String[] args) {
int[][] array = {{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
System.out.println(findTo(5, array));
}
}
public class Solution {
public static boolean Find(int target, int[][] array) {
for (int i = 0; i < array.length; i++) {
int low = 0;
int high = array[i].length - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (array[i][mid] > target) {
high = mid - 1;
}
if (array[i][mid] < target) {
low = mid + 1;
} else return true;
}
}
return false;
}
}
public static void main(String[] args) {
int[][] array = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
System.out.println(Find(7, array));
}
3. 替换空格
- 解法一:从头到尾扫描字符串,每次碰到空格字符的时候都进行替换。由于是1个字符替换成了3个字符,我们必须要把空格后面所有的字符都后移2个字节,否则就有两个字符被覆盖了。时间效率为O(n^2)。
- 解法二:在原来的字符串上移动字符。(从后向前移动。先遍历空格个数,设置字符串的长度,从后向前遍历移动字符串)。时间效率为O(n)。
public class ReplaceBlank {
public static String Replace(StringBuffer s) {
if (s.length() <= 0 && s == null) return "";
int numberOfBlack = 0;
int originalLength = s.length() - 1;
for (int i = 0; i < originalLength; i++) {
if (s.charAt(i) == ' ') {
numberOfBlack++;
}
}
int newLength = s.length() + numberOfBlack * 2;
int i = newLength -1;
s.setLength(newLength);
while (originalLength >= 0 && i > originalLength) {
if (s.charAt(originalLength) == ' ') {
s.setCharAt(i--, '0');
s.setCharAt(i--, '2');
s.setCharAt(i--, '%');
} else s.setCharAt(i--,s.charAt(originalLength));
originalLength--;
}
return s.toString();
}
public static void main(String[] args) {
StringBuffer str = new StringBuffer("We are happy");
System.out.println(Replace(str));
}
}
3.1 两个有序数组 A1 A2 的合并
public class OrderArrayMerge {
public static int[] merge(int[] A1, int[] A2) {
if (A1 == null && A2 == null) return null;
int A1A2Length = A1.length - 1;
int A2Length = A2.length - 1;
int A1Length = A1.length - A2.length - 1;
if (A2.length <= 0) return A1;
while (A2Length >= 0 && A1Length >= 0) {
if (A2[A2Length] >= A1[A1Length]) {
A1[A1A2Length] = A2[A2Length--];
} else A1[A1A2Length] = A1[A1Length--];
A1A2Length--;
}
return A1;
}
public static void main(String[] args) {
int[] A1 = {1, 5, 7, 8, 9, 12, 20, 39, 0, 0, 0, 0, 0, 0, 0};
int[] A2 = {3, 5, 7, 13, 15, 23, 45};
for (int num : merge(A1, A2)) {
System.out.println(num);
}
}
}