(一)merge sorted arrays
https://leetcode.com/problems/merge-sorted-array/description/
题目:将有序数组nums2合并到有序数组nums1中(num1空间足够,m、n分别表示两个数组里初始化的元素个数;
解答:从nums1的第m+n-1个位置开始更新(从最大的开始),如果从最小的开始更新需要不断将最大元素后移,浪费很多时间;
代码:
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int index = m + n - 1;
int index1 = m - 1;
int index2 = n - 1;
while (index1 >= 0 && index2 >=0) {
if (nums1[index1] > nums2[index2]) {
nums1[index--] = nums1[index1--];
} else {
nums1[index--] = nums2[index2--];
}
}
while (index1 >= 0) {
nums1[index--] = nums1[index1--];
}
while (index2 >= 0) {
nums1[index--] = nums2[index2--];
}
}
}
(二)intersection of two arrays(多种方法详见http://blog.csdn.net/joycetlm/article/details/76534550)
https://leetcode.com/problems/intersection-of-two-arrays/description/
题目:求两个数组的交集(1.不含重复元素 2.含重复元素);
解答:1.先将两数组排序,两个数组从0开始依次比较(跳过重复元素),较小的数组index加1后继续比较;将重合元素放在初始长度和nums1相同的temp数组中;最后将temp数组中的有效元素移到最终结果数组中;
2.同上,不跳过重复元素;
代码:
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int[] temp = new int[nums1.length];
int index = 0;
int index1 = 0, index2 = 0;
while (index1 < nums1.length && index2 < nums2.length) {
if (index1 > 0 && nums1[index1] == nums1[index1 - 1]) {
index1++;
continue;
}
if (nums1[index1] == nums2[index2]) {
temp[index++] = nums1[index1];
index1++;
index2++;
} else if (nums1[index1] < nums2[index2]) {
index1++;
} else {
index2++;
}
}
int[] res = new int[index];
for (int i = 0; i < index; i++) {
res[i] = temp[i];
}
return res;
}
}
(三)Search in Rotated Sorted Array (二分法)
https://leetcode.com/problems/search-in-rotated-sorted-array/description/
题目:一个已排序数组(无重复元素)在中间某个位置翻转了一下(如:4,5,6,1,2,3),在该数组中搜索某个数,若搜不到则返回-1;
解答:将start与mid所在位置值进行比较:
1、若start < mid,则说明mid左边是升序排列,因此判断target是否在左侧范围,若在范围内则将搜索范围缩小至左边,否则将范围定在右边;
2、若start > mid, 则说明mid右边升序排列,因此判断target是否在右侧范围,若在范围内则将搜索范围缩小至右边,否则将范围定在左边;
该题使用二分法,时间复杂度为O(logn)
代码:
class Solution {
public int search(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0, end = nums.length - 1;
while (start + 1 < end) {
int mid = (end + start) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[start] < nums[mid]) {
if (nums[start] <= target && nums[mid] > target) {
end = mid;
} else {
start = mid;
}
} else {
if (nums[mid] < target && nums[end] >= target) {
start = mid;
} else {
end = mid;
}
}
}
if (nums[start] == target) {
return start;
}
if (nums[end] == target) {
return end;
}
return -1;
}
}
Follow Up: https://leetcode.com/problems/search-in-rotated-sorted-array-ii/description/
问题:若含有重复元素,时间复杂度会发生变化吗?
解答:最坏的情况是数组为[1,1,1,...,1]中间有一个0;该情况无法使用二分时间复杂度为O(n);只需在原程序基础上加上一个nums[start] == nums[mid]的情况(或者直接使用for循环遍历整个数组进行查找)
代码:
class Solution {
public boolean search(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return false;
}
int start = 0, end = nums.length - 1;
while (start + 1 < end) {
int mid = (end + start) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[start] == nums[mid]) {
start += 1;
continue;
}
if (nums[start] < nums[mid]) {
if (nums[start] <= target && nums[mid] > target) {
end = mid;
} else {
start = mid;
}
} else {
if (nums[mid] < target && nums[end] >= target) {
start = mid;
} else {
end = mid;
}
}
}
if (nums[start] == target || nums[end] == target) {
return true;
}
return false;
}
}