LeetCode练习题【java】(2)

1、三个数的最大乘积(线性扫描)

/**
 * 三个数的最大乘积
 * 整型数组nums,在数组中找出由三个数字组成的最大乘积,并输出这个乘积。
 * 乘积不会越界
 * 重点考察:线性扫描
 */
public class ThreeNumbersMaxProduct {
    public static void main(String[] args) {
        int[] arr = new int[]{1, -5, 7, -2, 3};
        System.out.println(calculate(arr));
        System.out.println(calculate2(arr));
    }

    //先排序,再分两类讨论
    public static int calculate(int[] arr) {
        Arrays.sort(arr);
        int len = arr.length;
        return Math.max(arr[len - 1] * arr[len - 2] * arr[len - 3], arr[0] * arr[1] * arr[len - 1]);
    }

    //线性扫描
    public static int calculate2(int[] arr) {
        int min1 = Integer.MAX_VALUE;
        int min2 = Integer.MAX_VALUE;
        int max1 = Integer.MIN_VALUE;
        int max2 = Integer.MIN_VALUE;
        int max3 = Integer.MIN_VALUE;

        for (int i : arr) {
            if (i < min1) {
                min2 = min1;
                min1 = i;
            } else if (i < min2) {
                min2 = i;
            }
            if (i > max1) {
                max3 = max2;
                max2 = max1;
                max1 = i;
            } else if (i > max2) {
                max3 = max2;
                max2 = i;
            } else if (i > max3) {
                max3 = i;
            }
        }
        return Math.max(max1 * max2 * max3, min1 * min2 * max1);
    }
}

2、无序数组的两数之和(暴力法、HashMap)

/**
 * 两数之和 - 无序数组
 * 给定一个整数数组numbers ,从数组中找出两个数满足相加之和等于目标数 target
 * 假设每个输入只对应唯一的答案,而且不可以重复使用相同的元素。
 * 返回两数的下标值,以数组形式返回
 */
public class TwoNumbersSum {
    public static void main(String[] args) {
        int[] arr = new int[]{1,3,5,6,7};
        System.out.println(Arrays.toString(bf(arr,9)));
        System.out.println(Arrays.toString(hashMap(arr,9)));
    }

    //暴力法
    public static int[] bf(int[] arr,int target){
        for (int i = 0; i < arr.length; i++) {
            for (int j = i + 1; j < arr.length; j++) {
                if(arr[i] + arr[j] == target){
                    return new int[]{i,j};
                }
            }
        }
        return new int[0];
    }

    //使用HashMap
    public static int[] hashMap(int[] arr ,int target){
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < arr.length; i++) {
            if(map.containsKey(target - arr[i])){
                return new int[]{map.get(target - arr[i]),i};
            }
            map.put(arr[i],i);
        }
        return new int[0];
    }
}

3、有序数组的两数之和(二分法、双指针)

/**
 * 两数之和 - 有序数组
 * 给定一个整数有序数组numbers ,从数组中找出两个数满足相加之和等于目标数 target
 * 假设每个输入只对应唯一的答案,而且不可以重复使用相同的元素。
 * 返回两数的下标值,以数组形式返回
 */
public class TwoNumbersSumSort {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        System.out.println(Arrays.toString(binarySearch(arr, 9)));
        System.out.println(Arrays.toString(twoPoint(arr, 9)));
    }

    //二分法
    public static int[] binarySearch(int[] arr, int target) {
        for (int i = 0; i < arr.length; i++) {
            int left = i, right = arr.length - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                if (arr[mid] == target - arr[i]) {
                    return new int[]{i, mid};
                } else if (arr[mid] < target - arr[i]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
        }
        return new int[0];
    }

    //双指针
    public static int[] twoPoint(int[] arr, int target) {
        int left = 0, right = arr.length - 1;
        while (left < right) {
            if (arr[left] + arr[right] == target) {
                return new int[]{left, right};
            } else if (arr[left] + arr[right] < target) {
                left++;
            } else {
                right--;
            }
        }
        return new int[0];
    }
}

4、求取斐波那契数列第N位的值(递归、双指针迭代)

/**
 * 斐波那契数列
 * 求取斐波那契数列第N位的值
 * 斐波那契数列:每一位的值等于他前两位数字之和。前两位固定0,1,1,2,3,5,8...
 */
public class FibonacciSequence {
    public static void main(String[] args) {
        System.out.println(recursion(6));
        System.out.println(removeRecursion(6));
        System.out.println(twoPoint(6));
    }

    //递归
    public static int recursion(int n) {
        if (n == 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        return recursion(n - 1) + recursion(n - 2);
    }

    //去重递归
    public static int removeRecursion(int n) {
        int[] arr = new int[n + 1];
        return recurse(arr, n);
    }

    public static int recurse(int[] arr, int n) {
        if (n == 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        if (arr[n] != 0) {
            return arr[n];
        }
        arr[n] = recurse(arr, n - 1) + recurse(arr, n - 2);
        return arr[n];
    }

    //双指针迭代
    public static int twoPoint(int n){
         if (n == 0){
             return 0;
         }
         if(n==1){
             return 1;
         }
         int left = 0,right=1;
         int sum = 0;
        for (int i = 2; i <= n; i++) {
            sum = left + right;
            left = right;
            right = sum;
        }
        return right;
    }
}

5、排列硬币(二分法、牛顿迭代)

/**
 * 排列硬币
 * 总共有n枚硬币,将它们摆成一个阶梯形状,第k行就必须正好有k枚硬币。
 * 给定一个数字n,找出可形成完整阶梯行的总行数。n是一个非负整数,并且在32位有符号整型的范围内。
 */
public class ArrangeCoins {
    public static void main(String[] args) {
        System.out.println(iteration(11));
        System.out.println(binarySearch(11));
        System.out.println(newton(11));
    }

    //迭代
    public static int iteration(int n) {
        for (int i = 1; i <= n; i++) {
            n = n - i;
            if (n <= i) {
                return i;
            }
        }
        return 0;
    }

    //二分法
    public static int binarySearch(int n) {
        int left = 1, right = n;
        while (left <= right) {
            int mid = (left + right) / 2;
            int sum = (mid * (mid + 1)) / 2;
            if (sum == n) {
                return mid;
            } else if (sum < n) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return right;
    }

    //牛顿迭代
    public static int newton(int n) {
        if (n == 0) {
            return 0;
        }
        return (int) recurse(n, n);
    }

    public static double recurse(double x, int n) {
        double res = (x + (2 * n - x) / x) / 2;
        if (res == x) {
            return x;
        } else {
            return recurse(res, n);
        }
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fly-ping

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值