算法原型

/**
 1. 求数组中等于给定值的最长子数组
 */
public class LongestSubArrayEqualsAim {

    public static int solve(int[] arr, int target) {
        if (arr == null || arr.length == 0)
            return 0;

        //key:sum value:pos
        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0, -1);
        int res = 0;
        int sum = 0;

        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
            if (map.containsKey(sum - target)) {
                res = Math.max(i - map.get(sum - target), res);
            }

            if (!map.containsKey(sum)) {
                map.put(sum, i);
            }
        }
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {7, 1, 2, 3, 1, 4, 2, 1, -1, -2, 1, 2, -7, 7, 6, 3};
        int[] arr1 = {7, 7, 7, 7, 7, 7, 7, 7, 1, 2, 3, 1};
        System.out.println(solve(arr, 7));
        System.out.println(solve(arr1, 7));
    }
}

算法扩展

一个数组中既有奇数又有偶数,求奇数和偶数个数相等的最长的子数组

思路:将奇数记为-1,偶数记为1,题目转换为求数组中等于0的最长子数组

 public static int solve1(int[] arr) {
        if (arr == null || arr.length == 0)
            return 0;

        for (int i = 0; i < arr.length; i++) {
            if ((arr[i] & 1) == 1) {
                arr[i] = -1;
            } else {
                arr[i] = 1;
            }
        }

        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0, -1);
        int sum = 0;
        int res = 0;

        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
            if (map.containsKey(sum)) {
                res = Math.max(i - map.get(sum), res);
            }
            if (!map.containsKey(sum)) {
                map.put(sum, i);
            }
        }
        return res;
    }