算法之 统计集合元素相加为给定值的组合数(高效版)

第一题 : 统计数组两项相加为给定值的个数
看题很容易 三种解法 第一种用两个for循环暴力破解一样
第二种 一个for循环里通过二分查找-value(两项效果不明显)
第三种 通过排序 在通过排序的信息一遍for循环
下面几题上三种方法均适用(不过是加个for循环),前两种就不给代码了,下面贴出以下几题的第三种方法代码,有错误还望指出

TwoSum.java

import java.util.Arrays;

import edu.princeton.cs.algs4.StdRandom;

public class TwoSumFaster {
    private int[] a;
    public TwoSumFaster(int N)
    {
        a = new int[N];
        int MAX = 100000;
        for (int i = 0; i < N; ++i)
            a[i] = StdRandom.uniform(-MAX,MAX);
        Arrays.sort(a);
    }
    public TwoSumFaster()
    {

    }
    public void copyArray(int[] b)
    {
        a = new int[b.length];
        for (int i = 0; i < a.length; ++i)
            a[i] = b[i];
        Arrays.sort(a);
    }
    public int count(int target)
    {
        int lo = 0;
        int hi = a.length - 1;
        int count = 0;
        while (lo <= hi)
        {
            if (a[lo] + a[hi] == target)
                ++count;
            if (a[lo] + a[hi] <= target)
                ++lo;
            else
                --hi;
        }
        return count;
    }
}

第二题:统计数组三项相加为给定值的个数
ThreeSumFaster.java

import java.util.Arrays;

import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

public class ThreeSumFaster {
    private int[] a;
    public ThreeSumFaster(int N)
    {
        int MAX = 100000;
        a = new int[N];
        for (int i = 0; i < N; ++i)
            a[i] = StdRandom.uniform(-MAX,MAX);
        Arrays.sort(a);
    }
    public ThreeSumFaster()
    {

    }
    // for debug
    public void copyArray(int[] b)
    {
        a = new int[b.length];
        for (int i = 0; i < a.length; ++i)
            a[i] = b[i];
        Arrays.sort(a);
    }
    public int count(int target)
    {
        int lo = 0;
        int hi = a.length - 1;
        int count = 0;
        int mid;
        boolean flag;
        while (lo + 1 < hi)
        {
            flag = true;
            for (mid = lo + 1; mid < hi; ++mid)
            {
                if (a[lo] + a[hi] + a[mid] == target)
                    ++count;
                else if (a[lo] + a[hi] + a[mid] > target)
                {
                    --hi;
                    flag = false;
                    break;
                }
            }
             if (flag)
                 ++lo;
    }
        return count;
    }
}

第三题: 统计数组四项相加为给定值的个数
FourSumFaster.java

import java.util.Arrays;

import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

public class FourSumFaster {
    private int[] a;
    public FourSumFaster(int N)
    {
        a = new int[N];
        int MAX = 100000;
        for (int i = 0; i < N; ++i)
            a[i] = StdRandom.uniform(-MAX,MAX);
        Arrays.sort(a);
    }
    public FourSumFaster()
    {

    }
    public void copyArray(int[] b)
    {
        a = new int[b.length];
        for (int i = 0; i < a.length; ++i)
            a[i] = b[i];
        Arrays.sort(a);
    }
    public int count(int target)
    {
        int lo = 0;
        int hi = a.length - 1;
        int f_mid = 1;
        int s_mid = 2;
        int count = 0;
        boolean flag;
        while (lo + 2 < hi)
        {
            flag = true;
            for (f_mid = lo + 1; f_mid < s_mid; ++f_mid)
                for (s_mid = f_mid + 1; s_mid < hi; ++s_mid)
                {
                    if (a[lo] + a[f_mid] + a[s_mid] + a[hi] == target)
                        ++count;
                    if (a[lo] + a[f_mid] + a[s_mid] + a[hi] > target)
                        break;
                }
                ++lo;--hi;
        }
        return count;
    }
}

测试: main.java

import edu.princeton.cs.algs4.StdOut;

public class Main {
    public static void main(String[] args)
    {
        int[] a = {-10,-7,-4,-3,3,7,10,4};
        int[] b = {-5,-1,2,3,6,6};
        int[] c = {-5,-4,-3,-2,2,4,5,3};
        TwoSumFaster  wsf = new TwoSumFaster();
        ThreeSumFaster tsf = new ThreeSumFaster();
        FourSumFaster fsf = new FourSumFaster();
        wsf.copyArray(a);
        tsf.copyArray(b);
        fsf.copyArray(c);
        StdOut.println(wsf.count(0));
        StdOut.println(tsf.count(0));
        StdOut.println(fsf.count(0));
    }
}

运行:

算法之 统计集合元素相加为给定值的组合数(高效版)_第1张图片

你可能感兴趣的:(算法)