lintcode - Array算法题

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;
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值