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)); } }