博主头像
7024w的自留地

觉宇宙之无穷,识盈虚之有数

<算法很美> 部分习题

1.升序数组中寻找两数相加等于K
我使用的是双指针的方法,时间复杂度为o(n)
老师讲还可以通过二分法来查找(比如从第一个开始,K-arr[0],二分法寻找数组中是否存在符合条件的数)

//升序数组,找到两数之和等于K
public static int[][] findTwoNumbers(int[] arr,int k){
    int length = arr.length;
    int[][] ans = new int[length/2][2];
    int anslength  = 0;
    int left = 0;
    int right = length-1;
    //先找到最大的可能数
    while(arr[right] > k){
        right--;
    }
    //找到最小的左边可能数
    while(arr[left]+arr[right] < k ){
        left++;
    }
    while(left<right){
        int sum = arr[left] + arr[right];
        //说明数小了,左指针右移
        if(sum < k){
            left++;
            //说明数大了,右指针左移
        }else if(sum >k){
            right--;
        }else{
            ans[anslength][0] = arr[left];
            ans[anslength++][1] = arr[right];
            left++;
        }
    }
    return ans;
}


//拓展:如果是寻找三个数相加等于10呢?
public static int[][] findTwoNumbers3(int[] arr,int k){
    int length = arr.length;
    int[][] ans = new int[length/3][3];
    int ansLength = 0;
    int left = 0;
    int right = length-1;
    //先找到最大的可能数
    while(arr[right] > k){
        right--;
    }
    //找到最小的左边可能数
    while(arr[left]+arr[right] < k ){
        left++;
    }
    int mid = left+1;
    //只有找到了左指针才会改变,否则改变的是Mid
    while(mid<right) {
        //计算总和
        int sum = arr[left] + arr[right] + arr[mid];
        //如果sum>K 说明右指针向左移
        if(sum > k){
            right--;
        }else if(sum<k){
            //中间指针右移
            mid++;
        }else{
            //找到所求的三个数
            ans[ansLength][0] =  arr[left];
            ans[ansLength][1] = arr[mid];
            ans[ansLength++][2] = arr[right];
            //左指针向右移一位 此处右指针不宜改变,万一下一个数和目前下标的值也一样呢?
            left++;
            mid = left+1;
        }
    }
    return ans;
}

PS:感觉双指针应该算入门了把...

发表新评论