1.合并数组
题目要求:合并两个排序的整数数组A和B变成一个新的数组。
给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6]
你能否优化你的算法,如果其中一个数组很大而另一个数组很小?
思路:思路:只需要从后往前比较就可以了
public static void mergeSortedArray(int[] A, int[] B) {
// write your code here
int m = A.length - 1; // A length
int n = B.length - 1; // B length
int k = A.length + B.length - 1 ;
while(m >= 0 && n >= 0) //由于数组 加起来 两个比较一下就可以了
{
if(A[m] > B[n])
A[k--] = A[m--];
if(A[m] < B[n])
A[k--] = B[n--];
}
while(n > 0){
A[k--] = B[n --];
}
}
- second version
//使用的归并法 创建一个空间 然后分别比较
public static int[] mergeSortedArray1(int[] A,int[] B){
int[] answer = new int[A.length + B.length];
int i = 0 , j =0 ,k = 0;
//判断是否超过范围
while(i<A.length && j<B.length){
if(A[i] > B[j]){
answer[k] = B[j];
j++;
}
else
{
answer[k] = A[i];
i++;
}
k++;
}
//如果A.length > B.length
while(i < A.length){
answer[k] = A[i];
i++;
k++;
}
//B.length > A.length
while(j < B.length){
answer[k] = B[j];
j++;
k++;
}
return answer;
}
2.数组划分:
- description:给出一个整数数组 nums 和一个整数 k。划分数组(即移动数组 nums 中的元素),使得:
- 所有小于k的元素移到左边 所有大于等于k的元素移到右边
- 返回数组划分的位置,即数组中第一个位置 i,满足 nums[i] 大于等于 k。
- 使用 O(n) 的时间复杂度在数组上进行划分
public static int partitionArray(int[] nums, int k) {
//设置从左向右
if(nums == null) return 0;
int l = 0 , r = nums.length - 1;
while(l <= r){
while(l<= r && nums[l] < k) l++;
while(l<= r && nums[r] >= k) r--; //!!!! nums[r] > k xxxxx 看题目 >=的才行
//接下来 遇到num[l] > k | num[r] < k 替换位置
if(l <= r){
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
//忘记了需要更新l r index节点
l++;
r--;
}
}
return l;
}
3.恢复旋转排序数组
- 给定一个旋转排序数组,在原地恢复其排序
- 什么是旋转数组? 比如,原始数组为[1,2,3,4], 则其旋转数组可以是[1,2,3,4], [2,3,4,1], [3,4,1,2], [4,1,2,3]
- [4,5,1,2,3] - > [1,2,3,4,5]
经过观察得到 比较两个值找到为1的那个索引 接着把第一个值移除添加即可 (善于应用list的api get remove add)
public static void recoverRotatedSortedArray(List<Integer> nums) {
int len = nums.size();
int index = -1;
for(int i=0;i < len-1 ;i++){
if(nums.get(i) > nums.get(i+1))
index = i;
}
//删掉头 加在尾巴上
for(int i=0;i< index+1;i++){
Integer item = nums.get(0);
nums.remove(item);
nums.add(item);
}
}
4.求子数组最大和
- 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和。
- 子数组最少包含一个数
- 给出数组[−2,2,−3,4,−1,2,1,−5,3],符合要求的子数组为[4,−1,2,1],其最大和为6
- 要求时间复杂度为O(n)
如果遍历每个candidate,然后进行比较,那么就能找到最大的maxSum了。
贪心算法:把所有的进行比较 maxSum是最大的值默认为第一个
sum > 0 加上这个值 ;sum < 0 没有必要 让sum = sum[i]重新找找
如果新的sum 和 max比较 sum > maxsum 需要更新
public int maxSubArray(int[] nums) {
// write your code here
int sum = nums[0];// >0 or <0
int maxSum = nums[0];
for(int i=1;i<nums.length;i++){
if(sum >= 0){
sum += nums[i];//sum >= 0 加上值
}
else
{
sum = nums[i];//sum < 0 弃掉之前的值 换新值
}
if(maxSum < sum){
maxSum = sum;
}
}
return maxSum;
}