Java刷题有感

3 篇文章 2 订阅

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ ა
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
系列专栏:xiaoxie的牛客网刷题系列专栏——CSDN博客●'ᴗ'σσணღ*
我的目标:"团团等我💪( ◡̀_◡́ ҂)" 

感谢您的阅读!

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​+关注(互三必回)!

今天在牛客网刷题时,碰到了两题,虽然很简单,但是往深处想,又有不一样的见解,所以博主就把感想写下来分享给大家

首先请先看题

我想很多人和我一样一开始觉得这题不是很简单嘛它的第n项的表达式都给出来了,解决这个问题不是轻松拿捏嘛直接

import java.util.Scanner;
 
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            double a =0;
            double b = 0;
            for(int i=1;i<=n;i++){
                b=b+Math.pow(-1,i-1)*(2*i-1);
                a=a+1.0/b;
            }
            System.out.printf("%.3f",a);
        }
    }
}

这样是可以算出答案的,但博主突然灵机一动,把分母的值算出来看一下就发现原来算出来之后,是有规律的啊

它的分母计算出来之后是 1 + -2 +3 -4 +5 -6+......既然知道了分母是这样的规律那我们就可以稍微的简化一下代码

import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        double sum = 0.0;
        int flag = 1;
        for (int i = 1; i <= n; i++) {
           sum +=flag*(1.0/i);
           flag = -flag; 
        }
        System.out.printf("%.3f", sum);

    }
}

虽然说两个方法不见得谁比谁好,特别是我修改后的代码也算是属于投机取巧,但博主想说的是,抛开这个问题不讲,在我们平时做题的时候多角度的看待问题,我觉得值得提倡

还有一题也是非常简单的一题

也是一样一开始博主是这样写的使用两个for循环来解

import java.util.*;
 
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int x=sc.nextInt();
        int count=0;
        for(int i=1;i<=x;i++){
            int sum=0;
            for(int j=1;j<=i;j++){
                sum+=j;
            }
            count+=sum;  
        }
        System.out.println(count);   

写完后博主突然发现这题不是可以用初高中的数学知识用求前n项和来解这题嘛于是博主修改一下代码,使用公式S=n*(n+1)/2 来解

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += (i * (i + 1)) / 2;
        }
        System.out.println(sum);
    }
}

其实这题一样也是说不上修改就比没修改的代码性能好到那里去,但是博主觉得在我们平常编译代码的时候,用一用数学的公式可以替我们简化一些代码,并且能够在解题时拓展我们的思维

让我们更好地理解数学公式优化代码。所以,下面来看一下这道题的解法。

首先,我们来看一下题目要求的函数:

public boolean canJump(int[] nums) { 
// TODO: Implement the logic here return false;
 // Placeholder return statement }

题目要求我们实现一个函数,判断一个数组 nums 中的元素能否跳跃到最后一个位置。而我们需要通过修改代码来使得函数的执行效率尽可能高。

接下来,我们来分析一下题目的思路。对于这道题,我们可以采用贪心算法的思路来解决。我们遍历数组中的每个位置,并实时维护能够跳跃到的最远位置。对于当前遍历到的位置,如果它在能够跳跃到的最远位置的范围内,那么我们就更新能够跳跃到的最远位置,否则,我们就判断当前位置是否能够跳跃到最远位置,如果不能,就直接返回 False。最后,如果我们遍历完了整个数组,且能够跳跃到最远位置,那么就返回 True。

具体思路可以用以下代码来实现:

public boolean canJump(int[] nums) {
    int n = nums.length;
    int maxPos = nums[0]; // 可以到达的最远位置
    for (int i = 1; i < n; i++) {
        if (maxPos >= i) { // 如果当前位置可以到达
            maxPos = Math.max(maxPos, i + nums[i]); // 更新最远能到达的位置
            if (maxPos >= n - 1) { // 如果已经到达数组末尾
                return true;
            }
        } else {
            return false; // 如果当前位置不能到达,直接返回 false
        }
    }
    return false; // 遍历完整个数组都没有到达数组末尾,直接返回 false
}

这段代码的时间复杂度为 O(n),因为我们只需要遍历一次整个数组就能得到结果。但是,我们可以通过一些数学公式来简化代码,使得时间复杂度更低。

我们观察一下上面的代码:

 maxPos = Math.max(maxPos, i + nums[i]);

我们在更新 max_pos 时,计算的是当前位置可以到达的最远位置 i + nums[i] 和已经可以到达的最远位置 max_pos 中的较大值。这里,我们可以使用一个变量来维护可以到达的最远位置,并且不用每次都调用 max 函数来更新它。

具体操作是,我们令一个整数变量 end 记录当前能够到达的最远位置,而变量 max_pos 则记录已经遍历过的位置中能够到达的最远位置。当我们遍历到位置 i 时,如果 i > end,那么说明当前位置无法到达,直接返回 False。否则,我们更新 end 的值为 max(end, i + nums[i]),然后判断更新后的 end 是否已经达到数组的末尾,如果是,就返回 True。

具体实现如下:

public boolean canJump(int[] nums) {
    int n = nums.length;
    int end = 0; // 当前能够到达的最远位置
    for (int i = 0; i < n; i++) {
        if (i > end) { // 当前位置无法到达
            return false;
        }
        end = Math.max(end, i + nums[i]); // 更新能够到达的最远位置
        if (end >= n - 1) { // 如果已经到达末尾位置
            return true;
        }
    }
    return true;
}

这段代码的时间复杂度为 O(n),但是和上面的代码相比,更加简洁。这就是利用数学公式优化代码的方法。

谢谢大家的阅读!

评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小谢在努力

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

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

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

打赏作者

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

抵扣说明:

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

余额充值