【LEETCODE】50、数组分类,简单级别,题目:888,1013,896,485,448,697

package y2019.Algorithm.array;

import java.util.HashSet;
import java.util.Set;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.array
 * @ClassName: FairCandySwap
 * @Author: xiaof
 * @Description: TODO 888. Fair Candy Swap
 *
 * Alice and Bob have candy bars of different sizes: A[i] is the size of the i-th bar of candy that Alice has,
 * and B[j] is the size of the j-th bar of candy that Bob has.
 * Since they are friends, they would like to exchange one candy bar each so that after the exchange,
 * they both have the same total amount of candy.  (The total amount of candy a person has is the sum of the sizes of candy bars they have.)
 * Return an integer array ans where ans[0] is the size of the candy bar that Alice must exchange,
 * and ans[1] is the size of the candy bar that Bob must exchange.
 * If there are multiple answers, you may return any one of them.  It is guaranteed an answer exists.
 *
 * Input: A = [1,1], B = [2,2]
 * Output: [1,2]
 *
 * 交换A,B两个数组中的一个数字,使得两个数组的和相等。要返回的结果是个要交换的两个数字,分别来自A,B。
 *
 * @Date: 2019/7/8 9:25
 * @Version: 1.0
 */
public class FairCandySwap {

    public int[] solution(int[] A, int[] B) {
        //说白了对数组求和,然后求两个数组的平均数的差值,然后看看是否存在这个差值
        Set seta = new HashSet();
        int[] result = new int[2];
        int suma = 0, sumb = 0;

        for(int i = 0; i < A.length; ++i) {
            seta.add(A[i]);
            suma += A[i];
        }

        for(int i = 0; i < B.length; ++i) {
            sumb += B[i];
        }
        //求两边数据跟平均数的差值,两边的和的平均数就是两边需要到达的数据
        //现在求B距离这个平均数的差距
        int dif = (suma + sumb) / 2 - sumb;
        //然后我们再第二个数组中找,看是否存在正好对应的补上
        for(int i = 0; i < B.length; ++i) {
            //获取对应i的数据值,判断B加上这个差距值,判断A中是否存在
            //因为吧b[i]移动过去之后,还要减去B[i]的值
            if(seta.contains(dif + B[i])) {
                //看看A中是否包含这个差值,如果包含,那么就可以返回了
                result[0] = dif + B[i];
                result[1] = B[i];
//                break;
            }
        }

        return result;

    }

    public static void main(String args[]) {
        int[] A = {1,2};
        int[] B = {2,3};

        System.out.println(new FairCandySwap().solution(A, B));
    }

}

 

package y2019.Algorithm.array;

import java.util.stream.IntStream;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.array
 * @ClassName: CanThreePartsEqualSum
 * @Author: xiaof
 * @Description: TODO 1013. Partition Array Into Three Parts With Equal Sum
 * Given an array A of integers, return true if and only if we can partition the array into three non-empty parts with equal sums.
 * Formally, we can partition the array
 * if we can find indexes i+1 < j with (A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1])
 *
 * Input: [0,2,1,-6,6,-7,9,1,2,0,1]
 * Output: true
 * Explanation: 0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
 *
 * 题目的意思应该是平均吧数据分成三等分,每份的和相同,并且每份数据要求是连续的
 *
 * @Date: 2019/7/9 9:18
 * @Version: 1.0
 */
public class CanThreePartsEqualSum {

    public boolean solution(int[] A) {
        int sum = IntStream.of(A).sum(); //求和
        //分成三份
        int threeFen = sum / 3;
        //我们连续操作,获取,直到获取到三份
        boolean result = false;

        int index = 0;
        int tempSum = 0;
        int times = 0;
        while(index < A.length) {
            tempSum += A[index];
            if(tempSum == threeFen) {
                times++;
                tempSum = 0;
            }

            ++index;
        }

        if(times == 3) {
            result = true;
        }

        return result;
    }

}

 

 

package y2019.Algorithm.array;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.array
 * @ClassName: IsMonotonic
 * @Author: xiaof
 * @Description: TODO 896. Monotonic Array
 * An array is monotonic if it is either monotone increasing or monotone decreasing.
 * An array A is monotone increasing if for all i <= j, A[i] <= A[j].
 * An array A is monotone decreasing if for all i <= j, A[i] >= A[j].
 * Return true if and only if the given array A is monotonic.
 *
 * Input: [1,2,2,3]
 * Output: true
 *
 * 根据题意,这个数组应该是单向数组,递增,或者递减
 *
 * @Date: 2019/7/9 9:31
 * @Version: 1.0
 */
public class IsMonotonic {

    public boolean solution(int[] A) {
        int direct = 0; //数组变化方向
        int curNum = A[0];

        for(int i = 1; i < A.length; ++i) {

            if(A[i] > curNum && (direct == 0 || direct == 1)) {
                direct = 1;
                curNum = A[i];
            } else if(A[i] < curNum && (direct == 0 || direct == 2)) {
                direct = 2;
                curNum = A[i];
            } else if (A[i] == curNum) {
                curNum = A[i];
            } else {
                return false;
            }
        }

        return true;

    }

    public static void main(String args[]) {
        int[] A = {1,1,0};
        int[] B = {2,3};

        System.out.println(new IsMonotonic().solution(A));
    }

}

 

package y2019.Algorithm.array;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.array
 * @ClassName: FindMaxConsecutiveOnes
 * @Author: xiaof
 * @Description: TODO 485. Max Consecutive Ones
 * Given a binary array, find the maximum number of consecutive 1s in this array.
 *
 * Input: [1,1,0,1,1,1]
 * Output: 3
 * Explanation: The first two digits or the last three digits are consecutive 1s.
 *     The maximum number of consecutive 1s is 3.
 *
 * 统计最大1连续出现次数
 *
 * @Date: 2019/7/9 10:17
 * @Version: 1.0
 */
public class FindMaxConsecutiveOnes {

    public int solution(int[] nums) {

        int maxTimes = 0;
        int cnt = 0;
        for(int i = 0; i < nums.length; ++i) {
            if(nums[i] == 1) {
                cnt++;
            } else {
                if(cnt > maxTimes) {
                    maxTimes = cnt;
                }
                cnt = 0;
            }
        }

        //如果一直延续到循环末尾还是还是没有else,那么这里做最后拦截
        if(cnt > maxTimes) {
            maxTimes = cnt;
        }

        return maxTimes;
    }

}

 

package y2019.Algorithm.array;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.array
 * @ClassName: FindDisappearedNumbers
 * @Author: xiaof
 * @Description: TODO 448. Find All Numbers Disappeared in an Array
 * Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
 * Find all the elements of [1, n] inclusive that do not appear in this array.
 * Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
 *
 * Input:
 * [4,3,2,7,8,2,3,1]
 *
 * Output:
 * [5,6]
 *
 * @Date: 2019/7/9 10:25
 * @Version: 1.0
 */
public class FindDisappearedNumbers {

    public List<Integer> solution(int[] nums) {
        List ret = new ArrayList();
        for(int i = 0; i < nums.length; ++i) {
            int val = Math.abs(nums[i]) - 1; //用来做下标位置
            if(nums[val] > 0) {
                nums[val] = -nums[val];//标记val大小的数据
            }
        }

        //遍历获取没有标记的数据
        for(int i = 0; i < nums.length; ++i) {
            if(nums[i] > 0) {
                ret.add(i + 1); //这个位置是没有标记到的
            }
        }

        return ret;
    }

    public static void main(String args[]) {
        int[] A = {4,3,2,7,8,2,3,1};
        int[] B = {2,3};

        System.out.println(new FindDisappearedNumbers().solution(A));
    }

}

 

package y2019.Algorithm.array;

import java.util.HashMap;
import java.util.Map;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.array
 * @ClassName: FindShortestSubArray
 * @Author: xiaof
 * @Description: TODO 697. Degree of an Array
 * Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any
 * one of its elements.
 * Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums.
 *
 * Input: [1, 2, 2, 3, 1]
 * Output: 2
 * Explanation:
 * The input array has a degree of 2 because both elements 1 and 2 appear twice.
 * Of the subarrays that have the same degree:
 * [1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
 * The shortest length is 2. So return 2.
 *
 * 最短的子串使得其包含出现次数最多的元素,子串中刚好包含出现次数最多的数字
 *
 * @Date: 2019/7/9 14:06
 * @Version: 1.0
 */
public class FindShortestSubArray {

    public int solution(int[] nums) {
        //1.首先统计出现次数最多的数据
        Integer maxTimesNum = 0, times = 0;
        //这里第二个参数用来放一个数组,三个数据,第一个次数,第二个第一次出现位置,第三个最后一次出现位置
        Map<Integer, int[]> countMap = new HashMap();
        for(int i = 0; i < nums.length; ++i) {
            if(!countMap.containsKey(nums[i])) {
                //如果不包含
                countMap.put(nums[i], new int[]{1, i, i});
            } else {
                //如果已经包含了
                int[] temp = countMap.get(nums[i]);
                temp[0]++;
                temp[2] = i;
            }
        }

        //2.然后统计这个数据的子串,所有这个字符出现的次数达到最大次数就结束遍历
        int result = 0, maxTimes = 0;
        for(int[] values : countMap.values()) {
            if(values[0] > maxTimes) {
                //新的出现次数最大值
                maxTimes = values[0];
                //计算子串长度
                result = values[2] - values[1] + 1;
            } else if (values[0] == maxTimes) {
                //出现次数一样,取最小子串
                result = Math.min(result, values[2] - values[1] + 1);
            }
        }

        return result;
    }

    public static void main(String args[]) {
        int[] A = {1,2,2,3,1};
        int[] B = {2,1,1,2,1,3,3,3,1,3,1,3,2};

        System.out.println(new FindShortestSubArray().solution(B));
    }
}

 

posted @ 2019-07-09 14:51  cutter_point  阅读(261)  评论(0编辑  收藏  举报