Skip to content
qpzm7903 edited this page Aug 15, 2018 · 3 revisions

Array

P35

import org.junit.Test;

/**
 * Created by on 2018/8/7.
 * 对于有数数组,给定target,找出存在的index,或者插入的适合index
 */
public class P35 {
    public static int searchInsert(int[] nums, int target) {
        int low=0, high = nums.length-1;
        int middle= 0;
        while(low<=high){
            middle = low + (high - low) /2;
            if(nums[middle] > target){
                high = middle - 1;
            }else if (nums[middle] < target){
                low = middle + 1;
            }else if (nums[middle] == target){
                return middle;
            }
        }
        if(nums[middle] < target) return middle+1;
        return middle;
    }

    @Test
    public void test() {
        assert searchInsert(new int[]{1,3,5,6}, 5) == 2;
        assert searchInsert(new int[]{1,3,5,6}, 2) == 1;
        assert searchInsert(new int[]{1,3,5,6}, 7) == 4;
        assert searchInsert(new int[]{1,3,5,6}, 0) == 0;



    }
}

P66

import org.junit.Test;

/**
 * Created by on 2018/8/8.
 * 也就是数组加1运算,数组元素非负,且第一位不是0.
 */

public class P66 {
    public int[] plusOne(int[] digits) {
        int n = digits.length;
        int plus = 1;
        for (int i = n - 1; i >= 0; i--) {
            plus = (digits[i] + 1)/ 10;
            digits[i]= (digits[i]+1)%10;
            if(plus<=0) break;
        }
        if (digits[0] == 0) {
            int[] result = new int[n + 1];
            result[0] = 1;
            for(int i=0;i<n;i++) {
                result[i+1] = digits[i];
            }
            return result;
        }
        return digits;
    }

    @Test
    public void tset() {
//        System.out.println(plusOne(new int[]{1,2,3}));
        System.out.println(10%10);

        int[] result = plusOne(new int[]{9, 9, 9, 9});
        for (int a : result) {
            System.out.print(a +" ");
        }
    }
}

P119

import org.junit.Test;

/**
 * Created by on 2018/8/8.
 * 也就是数组加1运算,数组元素非负,且第一位不是0.
 */

public class P66 {
    public int[] plusOne(int[] digits) {
        int n = digits.length;
        int plus = 1;
        for (int i = n - 1; i >= 0; i--) {
            plus = (digits[i] + 1)/ 10;
            digits[i]= (digits[i]+1)%10;
            if(plus<=0) break;
        }
        if (digits[0] == 0) {
            int[] result = new int[n + 1];
            result[0] = 1;
            for(int i=0;i<n;i++) {
                result[i+1] = digits[i];
            }
            return result;
        }
        return digits;
    }

    @Test
    public void tset() {
//        System.out.println(plusOne(new int[]{1,2,3}));
        System.out.println(10%10);

        int[] result = plusOne(new int[]{9, 9, 9, 9});
        for (int a : result) {
            System.out.print(a +" ");
        }
    }
}

P167

import org.junit.Test;

/**
 * Created by on 2018/8/8.
 */
public class P167 {

    public int[] twoSum(int[] numbers, int target) {
        int j=0,i=0;
        for(;i<numbers.length;i++) {
            if ((j = binarySearch(numbers, target - numbers[i], i+1, numbers.length - 1)) != -1) {
                return new int[]{i, j};
            }
        }
        return new int[]{0, 0};
    }

    public int binarySearch(int[] numbers, int target, int start, int end) {
        while (start <= end) {
            int middle = start + (end - start) /2;
            if (numbers[middle] > target) {
                end = middle - 1;
            } else if (numbers[middle] < target) {
                start = middle + 1;
            } else {
                return middle;
            }
        }
        return -1;
    }
    @Test
    public void test() {
        int[] data = new int[]{2, 7, 11, 15};
        int[] result = twoSum(data,  22);
        for (int a : result) {
            System.out.print(a + " ");
        }

    }
}

P189

import org.junit.Test;

/**
 * Created by on 2018/8/8.
 */
public class P167 {

    public int[] twoSum(int[] numbers, int target) {
        int j=0,i=0;
        for(;i<numbers.length;i++) {
            if ((j = binarySearch(numbers, target - numbers[i], i+1, numbers.length - 1)) != -1) {
                return new int[]{i, j};
            }
        }
        return new int[]{0, 0};
    }

    public int binarySearch(int[] numbers, int target, int start, int end) {
        while (start <= end) {
            int middle = start + (end - start) /2;
            if (numbers[middle] > target) {
                end = middle - 1;
            } else if (numbers[middle] < target) {
                start = middle + 1;
            } else {
                return middle;
            }
        }
        return -1;
    }
    @Test
    public void test() {
        int[] data = new int[]{2, 7, 11, 15};
        int[] result = twoSum(data,  22);
        for (int a : result) {
            System.out.print(a + " ");
        }

    }
}

P283

import org.junit.Test;

/**
 * Created by on 2018/8/9.
 * 将数组中0的元素放到后面,非零元素相对位置不变
 * 进阶的要求是不适用额外的数组,最小化操作数量
 */
public class P283 {
    public void moveZeroes(int[] nums) {
        int end = checkZero(nums, nums.length - 1);
        for (int i = 0; i < end; i++) {
            if (nums[i] == 0) {
                nums[i] = nums[end];
                nums[end] = 0;
                end = checkZero(nums, end - 1);
            }
        }
    }

    public int checkZero(int[] nums, int pos) {
        for (int i = pos; i >= 0; i--) {
            if (nums[i] != 0) return i;
        }
        return nums.length;
    }

    /**
     * 错误的方法,相对位置变了
     */
    @Test
    public void test() {
        int[] nums = {0, 1, 0, 3, 12};
        moveZeroes(nums);
        for (int a : nums)
            System.out.print(a + " ");
    }


    public void moveZeroes1(int[] nums) {
        int j = 0, i = 0;
        for (; i < nums.length; i++) {
            if (i == nums.length - 1) break;
            if (nums[i] == 0) {
                move(nums, j, i + 1);
                j++;
            }
        }
    }

    public void move(int[] nums, int start, int end) {
        for (int i = start; i < end; i++) {
            int temp = nums[start];
            nums[start] = nums[start + 1];
            nums[start + 1] = temp;
        }
    }

    /**
     * 方法2测试
     * 依旧错误
     */
    @Test
    public void test2() {
        int[] nums = {0, 1, 0, 3, 12};
        moveZeroes1(nums);
        for (int a : nums)
            System.out.print(a + " ");
    }


    public void moveZeroes2(int[] nums) {
        int j = 0, i = 0;
        for (int k = 0; k < nums.length; k++)
            if (nums[k] == 0) {
                j = k;
                break;
            }
        for (; i < nums.length; i++) {
            if (nums[i] != 0 && nums[j] == 0) {
                swap(nums, i, j);
                j = findZero(nums, j + 1);

            }
        }
    }

    public void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    public int findZero(int[] nums, int start) {
        for (int k = start; k < nums.length; k++) {
            if (nums[k] == 0) return k;
        }
        return 0;
    }

    /**
     * 方法3测试
     * OK
     * 还需要测试没有0的数据
     *
     */
    @Test
    public void test3() {
        int[] nums = {0, 1, 0, 3, 12};
        moveZeroes2(nums);
        for (int a : nums)
            System.out.print(a + " ");
        System.out.println();
        int[] nums2 = {1,2,0,3,0};
        moveZeroes2(nums2);
        for(int a:nums2)
            System.out.print(a + " ");
        System.out.println();
        int[] nums3 = {0,1,0,0,0,2,0};
        moveZeroes2(nums3);
        for(int a:nums3)
            System.out.print(a +" ");
        System.out.println();
        int[] nums4 = {1,2};
        moveZeroes2(nums4);
        for(int a:nums4)
            System.out.print(a +" ");

    }

    /**
     * 使用额外的数组自然最简单了
     * @param nums
     */
    public void moveZeroes4(int[] nums) {
        int k = 0;
        int [] temp = new int[nums.length];
        for(int i=0;i<nums.length;i++)temp[i] = nums[i];
        for(int i=0;i<temp.length;i++){
            if(temp[i] != 0)
                nums[k++] = temp[i];
        }
        for(;k<nums.length;k++){
            nums[k] = 0;
        }
    }

    /**
     * 修正前三个方法
     */
    public void moveZeroes5(int[] nums) {
        int j=0;
        for(int i=0;i<nums.length;i++) {
            if(nums[i]!=0)
                nums[j++] = nums[i];
        }
        for(;j<nums.length;j++)
            nums[j] = 0;
    }

    @Test
    public void test5() {
        int[] nums = {0, 1, 0, 3, 12};
        moveZeroes5(nums);
        for (int a : nums)
            System.out.print(a + " ");
        System.out.println();
        int[] nums2 = {1,2,0,3,0};
        moveZeroes5(nums2);
        for(int a:nums2)
            System.out.print(a + " ");
        System.out.println();
        int[] nums3 = {0,1,0,0,0,2,0};
        moveZeroes5(nums3);
        for(int a:nums3)
            System.out.print(a +" ");
        System.out.println();
        int[] nums4 = {1,2};
        moveZeroes5(nums4);
        for(int a:nums4)
            System.out.print(a +" ");
    }
}

P442

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Created by on 2018/8/14.
 * 找出所有出现两次的元素
 * 进阶:
 * 不使用额外的空间以及使用O(n)的时间,一下思路厉害!
 *     // when find a number i, flip the number at position i-1 to negative.
 // if the number at position i-1 is already negative, i is the number that occurs twice.

 public List<Integer> findDuplicates(int[] nums) {
 List<Integer> res = new ArrayList<>();
 for (int i = 0; i < nums.length; ++i) {
 int index = Math.abs(nums[i])-1;
 if (nums[index] < 0)
 res.add(Math.abs(index+1));
 nums[index] = -nums[index];
 }
 return res;
 }

 因为 1<= a[i] <= n n为数组的size
 所以恰好可以用counting 方法
 */
public class P442 {
    public List<Integer> findDuplicates(int [] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        List<Integer> list = new LinkedList<>();
        for(int i=0;i<nums.length;i++) {
            if (map.get(nums[i]) != null) {
                map.put(nums[i], 2);
                list.add(nums[i]);
            } else {
                map.put(nums[i], 1);
            }
        }
        return list;
    }


}

P448

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by on 2018/8/15.
 * 1 ≤ a[i] ≤ n n为数组大小,
 * 输出没有在范围里的数字
 * 进阶是不使用额外的空间,返回的list不算额外的空间。并且使用O(n)的时间。
 * 如果不使用counting数组来辅助的话,直接使用ArrayList?好像也是可以的
 * 看一段优秀的代码,使用nums[nums[i] -1] = -nums[nums[i]-1]标记见过的
 *
 * public List<Integer> findDisappearedNumbers(int[] nums) {
 List<Integer> ret = new ArrayList<Integer>();

 for(int i = 0; i < nums.length; i++) {
 int val = Math.abs(nums[i]) - 1;
 if(nums[val] > 0) {
 nums[val] = -nums[val];
 }
 }

 for(int i = 0; i < nums.length; i++) {
 if(nums[i] > 0) {
 ret.add(i+1);
 }
 }
 return ret;}
 */
public class P448 {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        List<Integer> res = new ArrayList<>();
        if(nums.length==0 || nums== null)return res;
        int[] counting = new int[nums.length + 1];
        for(int i=0;i<nums.length;i++) {
            counting[nums[i]]++;
        }
        for(int i=1;i<counting.length;i++) {
            if(counting[i] == 0 )
                res.add(i);
        }
        return res;
    }

    @Test
    public void test() {
        int[] nums = {4, 3, 2, 7, 8, 2, 3, 1};
        List<Integer> list = findDisappearedNumbers(nums);
        for (Integer a : list) {
            System.out.print(a + " ");
        }
    }
}

P485

/**
 * Created by on 2018/8/14.
 * 给定二进制数组,找到此数组中连续1的最大数量
 */
public class P485 {
    public int findMaxConsecutiveOnes(int[] nums) {
        int count = 0;
        int max = 0;
        for(int i=0;i<nums.length;i++){
            if(nums[i] == 1){
                count ++;
                if(max < count) max = count;
            }else{
                count =0;
            }
        }
        return max;
    }
}

P495

import org.junit.Test;

/**
 * Created by on 2018/8/15.
 * 提莫队长的攻击,计算中毒时间
 */
public class P495 {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        if(timeSeries.length == 0 || timeSeries == null || duration <= 0 ) return 0;
        int count = 0;
        int pre = timeSeries[0];
        for(int i=1;i<timeSeries.length;i++) {
            if (pre + duration > timeSeries[i]) {
                count += timeSeries[i] - pre;
            } else {
                count += duration;
            }
            pre = timeSeries[i];
        }
        count += duration;
        return count;
    }

    @Test
    public void  test() {
        int[] time = {1, 4};
        int duration = 2;
        assert findPoisonedDuration(time,duration) == 4;
        int[] time1 = {1, 2};
        int duration1 = 2;
        assert findPoisonedDuration(time1, duration1) ==3;
    }

    @Test
    public void test1() {
        int [] time = {};
        int duration = 100000;
        System.out.println(findPoisonedDuration(time,duration));
    }
}

P561

import java.util.Arrays;

/**
 * Created by on 2018/8/9.
 * 输入的数组数量为2N,则将2N个int分为N组,for i=0 to n sum+= min(ai,bi) 。理解起来就是,首先排序,然后把前面一半小的加起来?
 * 错误的理解
 *  [1,4,3,2] - > 4 =  min(1,2 )  + min(3,4)
 *  目的是让和最大。
 *  看的讨论里的证明,大致如下:
 *  首先设定每一对(ai,bi) 中 ai <= bi
 *  则sm = a1 + a2 + a3 ... + an
 *  di = bi - ai
 *  sa = a1 + b1 + ...an + bn
 *  sd = b1 - a1 + ... bn - an = d1 + d2 + ... dn
 *  sa = a1 + a1 + d1 + ...  = 2sm + sd
 *  sm = (sa - sd)/2 sa是常量,只要sd小,所以让每一对尽可能靠近。所以代码?
 */
public class P561 {
    public int arrayPairSum(int[] nums) {
        Arrays.sort(nums);
        int sum=0;
        for(int i=0;i<nums.length;i+=2) {
            sum+=nums[i];
        }
        return sum;
    }
}

P566

/**
 * Created by on 2018/8/14.
 * 将数组reshpae,行主序,按行填充。
 * public int[][] matrixReshape(int[][] nums, int r, int c) {
 if(nums.length == 0 || r * c > nums.length * nums[0].length)
 return nums;
 int[][] res = new int[r][c];
 int row = 0;
 int col = 0;

 for(int i = 0; i < nums.length; i++){
 for(int j = 0; j < nums[i].length; j++){
 res[row][col++] = nums[i][j];
 if(col == c){
 row++;
 col = 0;
 }
 }
 }
 return res;
 }

 */
public class P566 {
    public int[][] matrixReshape(int[][] nums, int r, int c) {
        int sum = nums.length*nums[0].length;
        if(sum < r *c )
            return nums;
        int [][] result = new int[r][c];
        int [] temp = new int[sum];
        int k=0;
        for(int i=0;i<nums.length;i++) {
            for(int j=0;j<nums[0].length;j++) {
                temp[k++] = nums[i][j];
            }
        }
        k = 0;
        for(int i=0;i<r;i++) {
            for(int j=0;j<c;j++) {
                result[i][j] = temp[k++];
            }
        }
        return result;
    }
}

P766

import org.junit.Test;

/**
 * Created by on 2018/8/10.
 *
 */


public class P766 {
    /**
     * 不够好的方法,这样进行了很多++操作,应该是对于每一个元素,都检查它与右下角的元素是否相同即可。检查的矩阵为 n-1 * m-1 。
     */
    public boolean isToeplitzMatrix(int[][] matrix) {
        int n = matrix.length;
        int m = matrix[0].length;
        int temp=0;
        for(int k=n-2;k>=0;k--) {
            for(int i=k, j=0,flag=0;i<n && j<m;i++,j++,flag++) {
                if (flag == 0) {
                    temp = matrix[i][j];

                } else if (temp == matrix[i][j]) {

                } else {
                    return false;
                }
            }
        }
        for(int k=m-2;k>=0;k--) {
            for(int i=0, j=k,flag=0;i<n && j<m;i++,j++,flag++) {
                if (flag == 0) {
                    temp = matrix[i][j];

                } else if (temp == matrix[i][j]) {

                } else {
                    return false;
                }
            }
        }
        return true;
    }

    @Test
    public void test() {
        int[][] matrix = {{1, 2, 3, 4}, {5, 1, 2, 3}, {9, 5, 1, 2}};
        assert true == isToeplitzMatrix(matrix);
        int [][] martix1 = {{0},{1},{1}};
        assert true == isToeplitzMatrix(martix1);
        int[][] matrix2 = {{1, 2}, {2, 2}};
        assert false == isToeplitzMatrix(matrix2);
    }


    /**
     * 更好的解决方法
     *
     */
    public boolean isToeplitzMatrix1(int[][] matrix) {
        for (int i = 0; i < matrix.length - 1; i++) {
            for (int j = 0; j < matrix[i].length - 1; j++) {
                if (matrix[i][j] != matrix[i + 1][j + 1]) return false;
            }
        }
        return true;
    }
}

P832

import org.junit.Test;

/**
 * Created by on 2018/8/9.
 * 给定二维数组表示图像,将图像水平翻转,然后反转,接着返回
 * 水平就是每一行都会反转,[1,0,1,0] -> [0,1,0,1]
 * 反转就是  [ [A] , [B] ] -> [ [B], [A] ]。
 */
public class P832 {
    public int[][] flipAndInvertImage(int[][] A) {
        for(int i=0;i<A.length;i++) {
            horizontallyFlip(A[i]);
            invert(A[i]);
        }
        return A;
    }

    public void horizontallyFlip(int[] nums) {
        int start=0,end=nums.length-1;
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;end--;
        }
    }

    public void invert(int[] nums) {
        for(int i=0;i<nums.length;i++) {
            nums[i] ^= 1;
        }
    }
    @Test
    public void test() {
        int[] nums = {1,0,0,1,1,1};
        horizontallyFlip(nums);
        int[] result = {1,1,1,0,0,1};
        for (int a : nums) {
            System.out.print(a +" ");
        }
//        System.out.println();
//        invert(nums);
//        for (int a : nums) {
//            System.out.print(a +" ");
//        }


    }
}

P867

/**
 * Created by on 2018/8/10.
 * 矩阵转置
 */
public class P867 {
    public int[][] transpose(int[][] A) {
        int n = A.length;
        int m = A[0].length;
        int [][] result = new int[m][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                result[j][i] = A[i][j];
            }
        }
        return result;
    }
}
Clone this wiki locally