LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解

简介: LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解

LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解

1 寻找数组的中心索引

解题思路与代码

数组中某一个下标,左右两边的元素之后相等,该下标即为中心索引

思路:先统计出整个数组的总和,然后从第一个元素开始叠加

总和递减当前元素,叠加递增当前元素,知道两个值相等

    public static int pivotIndex(int[] nums) {
        int sum1 = Arrays.stream(nums).sum();
        int sum2 = 0;
        for(int i = 0; i<nums.length; i++){
            sum2 += nums[i];
            if(sum1 == sum2){
                return i;
            }
            sum1 = sum1 - nums[i];
        }
        return -1;
    }

2 x的平方根

1 题目

在不使用 sqrt(x) 函数的情况下,得到 x的平方根的整数部分

2 解题思路与代码

解法一:二分查找

x的平方根肯定在0到x之间,使用二分查找定位该数字,该数字的平方一定是最接近x的,m平方值如果大于x、则往左边找,如果小于等于x则往右边找找到0和X的最中间的数m,

如果m * m > x,则m取x/2到x的中间数字,直到m * m < x,m则为平方根的整数部分

如果m * m <= x,则取0到x/2的中间值,知道两边的界限重合,找到最大的整数,则为x平方根的整数部分

间复杂度:O(logN)

代码

    public static int binarySearch(int x) {
        int l = 0, r = x, index = -1;
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if ((long) mid * mid <= x) {
                index = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return index;
    }

解法二:牛顿迭代

假设平方根是 i ,则 i 和 x/i 必然都是x的因子,而 x/i 必然等于 i ,推导出 i + x / i = 2 * i,得出 i = (i + x / i) / 2

由此得出解法,i 可以任选一个值,只要上述公式成立,i 必然就是x的平方根,如果不成立, (i + x / i) / 2得出的值进行递归,直至得出正确解

代码

    public static int newton(int x) {
        if(x==0) return 0;
        return ((int)(sqrts(x,x)));
    }
    public static double sqrts(double i,int x){
        double res = (i + x / i) / 2;
        if (res == i) {
            return i;
        } else {
            return sqrts(res,x);
        }
    }

3 三个数的最大乘积

1 题目

一个整型数组 nums ,在数组中找出由三个数字组成的最大乘积,并输出这个乘积。

乘积不会越界

如果数组中全是非负数,则排序后最大的三个数相乘即为最大乘积;如果全是非正数,则最大的三个数相乘同样也为最大乘积。

如果数组中有正数有负数,则最大乘积既可能是三个最大正数的乘积,也可能是两个最小负数(即绝对值最大)与最大正数的乘积。

分别求出三个最大正数的乘积,以及两个最小负数与最大正数的乘积,二者之间的最大值即为所求答案。

2 解题思路与代码

解法一:排序

    public static int sort(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        return Math.max(nums[0] * nums[1] * nums[n - 1], nums[n - 3] * nums[n - 2] *
                nums[n - 1]);
    }


解法二:线性扫描

public static int getMaxMin(int[] nums) {
        // 最小的和第二小的
        int min1 = 0, min2 = 0;
        // 最大的、第二大的和第三大的
        int max1 = 0, max2 = 0, max3 = 0;
        for (int x : nums) {
            if (x < min1) {
                min2 = min1;
                min1 = x;
            } else if (x < min2) {
                min2 = x;
            }
            if (x > max1) {
                max3 = max2;
                max2 = max1;
                max1 = x;
            } else if (x > max2) {
                max3 = max2;
                max2 = x;
            } else if (x > max3) {
                max3 = x;
            }
        }
        return Math.max(min1 * min2 * max1, max1 * max2 * max3);
    }

4 Leetcode 149:直线上最多的点数

题目描述

给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。

示例1:

输入: [[1,1],[2,2],[3,3]]
输出: 3
解释:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4


示例2:

输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4
解释:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6


解题代码

java

class Sulution{
    public int maxPoints(int[][] points){
        int n = points.length;
        if(n ==0 )
            return 0;
        if(n == 1)
            return 1;
        int res = 0;
        for (int i = 0; i < n-1; i++) {
            Map<String,Integer>slpe = new HashMap<>();
            int repeat = 0;
            int tmp_max = 0;
            for (int j =i +1;i<n; i++) {
                int dy = points[i][1] - points[j][1];
                int dx = points[i][0] - points[j][0];
                if (dy == 0 && dx == 0) {
                    repeat++;
                    continue;
                }
                int g = gcd(dy,dx);
                if (g != 0){
                    dy /= g;
                    dx /= g;
                }
                String tmp = String.valueOf(dy) +"/" + String.valueOf(dx);
                slope.put(tmp,slope.getOrDefault(tmp,0) + 1);
                tmp_max = Math.max(tmp_max,slope.get(tmp));
            }
            res = Math.max(res,repeat + tmp_max + 1);
        }
        return res;
    }
    private int gcd(int dy, int dx) {
        if (dx == 0)return dy;
        else
            return gcd(dx,dy % dx);
    }
}

python

from decimal import Decimal
Decimal((point2.y - point1.y))/Decimal((point2.x - point1.x))
class Solution:
    def maxPoints(self, points):
        """
        :type points: List[Point]
        :rtype: int
        """
        slopes, result = defaultdict(int), 0
        for i, point1 in enumerate(points): 
            slopes.clear()
            duplicate = 1
            for _, point2 in enumerate(points[i+1:]):
                if point1.x == point2.x and point1.y == point2.y:
                    duplicate += 1
                    continue

                slope = float('inf') if point1.x == point2.x else \
                            (point1.y - point2.y)/(point1.x - point2.x)

                slopes[slope] += 1

            if result < duplicate:
                result = duplicate

            for _, val in slopes.items():
                if val + duplicate > result:
                    result = val + duplicate

        return result

 

目录
相关文章
|
2月前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
3月前
|
存储 缓存 算法
Java 数组
【10月更文挑战第19天】Java 数组是一种非常实用的数据结构,它为我们提供了一种简单而有效的方式来存储和管理数据。通过合理地使用数组,我们能够提高程序的运行效率和代码的可读性。更加深入地了解和掌握 Java 数组的特性和应用,为我们的编程之旅增添更多的精彩。
39 4
|
3月前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
45 2
|
3月前
|
存储 Java
Java“(array) <X> Not Initialized” (数组未初始化)错误解决
在Java中,遇到“(array) &lt;X&gt; Not Initialized”(数组未初始化)错误时,表示数组变量已被声明但尚未初始化。解决方法是在使用数组之前,通过指定数组的大小和类型来初始化数组,例如:`int[] arr = new int[5];` 或 `String[] strArr = new String[10];`。
104 2
|
3月前
|
Java
Java数组动态扩容和动态缩减
Java数组动态扩容和动态缩减
30 3
|
3月前
|
存储 算法 Java
带你学习java的数组军队列
带你学习java的数组军队列
41 0
|
9天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
143 80
|
3天前
|
机器学习/深度学习 算法
基于遗传优化的双BP神经网络金融序列预测算法matlab仿真
本项目基于遗传优化的双BP神经网络实现金融序列预测,使用MATLAB2022A进行仿真。算法通过两个初始学习率不同的BP神经网络(e1, e2)协同工作,结合遗传算法优化,提高预测精度。实验展示了三个算法的误差对比结果,验证了该方法的有效性。
|
5天前
|
机器学习/深度学习 数据采集 算法
基于PSO粒子群优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目展示了基于PSO优化的CNN-GRU-SAM网络在时间序列预测中的应用。算法通过卷积层、GRU层、自注意力机制层提取特征,结合粒子群优化提升预测准确性。完整程序运行效果无水印,提供Matlab2022a版本代码,含详细中文注释和操作视频。适用于金融市场、气象预报等领域,有效处理非线性数据,提高预测稳定性和效率。
|
2天前
|
算法
基于梯度流的扩散映射卡尔曼滤波算法的信号预处理matlab仿真
本项目基于梯度流的扩散映射卡尔曼滤波算法(GFDMKF),用于信号预处理的MATLAB仿真。通过设置不同噪声大小,测试滤波效果。核心代码实现数据加载、含噪信号生成、扩散映射构建及DMK滤波器应用,并展示含噪与无噪信号及滤波结果的对比图。GFDMKF结合非线性流形学习与经典卡尔曼滤波,提高对非线性高维信号的滤波和跟踪性能。 **主要步骤:** 1. 加载数据并生成含噪测量值。 2. 使用扩散映射捕捉低维流形结构。 3. 应用DMK滤波器进行状态估计。 4. 绘制不同SNR下的轨迹示例。