【解题报告】《LeetCode零基础指南》(第三讲) 循环 - Java

在这里插入图片描述

零、流程控制

说到循环,就不得不提到一个词——流程控制。
顾名思义,就是根据不同的情况,来分别控制流程的走向,或者说重复执行某个流程。而后者,就是循环。下面列举几个我之前总结下来的几个流程:

1. if - else if - else

这个就比较好理解了,符合哪个条件就执行哪一行的代码。if可以单独使用,但是else if 和 else 不能单独使用。流程的大体结构如下所示:

if (条件表达式1){
	代码1;
} else if (条件表达式2){
    代码2;
} else {
    代码3;
}

2. switch

执行中一个case成立,从这个case向后穿透执行所有case,包括default直到结束,或者遇到break中断跳出switch。

  • 例子1:

    	public static void main(String[] args) {
            System.out.println("输入:");
            int i = new Scanner(System.in).nextInt();
            System.out.println("输出:");
            switch (i){
                case 1:
                    System.out.print(1 + " ");
                case 2:
                    System.out.print(2 + " ");
                default:
                    System.out.print(3 + " ");
            }
        }
    

    输入:
    1
    输出:
    1 2 3

  • 例子2:(加入 break)

    	public static void main(String[] args) {
            System.out.println("输入:");
            int i = new Scanner(System.in).nextInt();
            System.out.println("输出:");
            switch (i){
                case 1:
                    System.out.print(1 + " ");
                case 2:
                    System.out.print(2 + " ");
                    break;
                default:
                    System.out.print(3 + " ");
            }
        }
    

    输入:
    1
    输出:
    1 2

3. 循环

循环有三种:for、while、do-while,这几种循环理论上来说是可以相互转换的。

3.1 循环的种类

  • for
    执行顺序如下所示:① → ② → ③ → ④ → ② → ③ → ④ ……直到不符合执行条件,终止循环。
    一般明确循环次数时,使用for循环。
		for(①变量赋值;②执行条件;④变量修改){
            ③代码;
        }
  • while
    当符合判断条件,则进入循环执行代码,执行完继续判断条件表达式,循环执行知道不符合条件,终止循环。
    while循环的特点:先判断后执行,有可能一次都不执行。
		while (条件表达式){
            代码;
        }
  • do-while
    先执行一次代码,再判断条件表达式的值,后面的执行流程就跟while循环一样了。
    do-while循环的特点:先执行后判断,至少会执行一次代码。
	do {
           代码;
       } while (条件表达式);

3.2 循环的终止

  • break
    中断跳出switch或当前循环,这里的跳出当前循环是指终止执行循环
  • continue
    结束本轮循环,直接开始执行下一轮循环

3.3 循环的命名

		//循环1
       for (int i = 1;i < 10;i++){
           //循环2
           for (int j = 10;j > 0;j--){
               if (j == 5){
                   break;
               }
           }
       }

Q:就像上面的代码,循环1中嵌套循环2,,但是我希望当 j = 5 j = 5 j=5 时,跳出的不是循环2,而是外部的循环1,怎么办?
A:这时候就可以对循环进行命名,然后需要跳出循环时,指定要跳出的是哪个循环,当然,continue也适用。因此上面的代码可以改写成:

		//循环1
		//outer可以命名为其他名字,只是习惯上最外层循环命名为outer而已
        outer:
        for (int i = 1;i < 10;i++){
            //循环2
            for (int j = 10;j > 0;j--){
                if (j == 5){
                    break outer;
                }
            }
        }

一、剑指 Offer 64. 求1+2+…+n

1.题目

剑指 Offer 64. 求1+2+…+n

求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

限制:
1 <= n <= 10000

2.分析

等差数列求和公式: ( 首 项 + 末 项 ) ∗ 项 数 / 2 (首项+末项)*项数/2 (+)/2

3.代码

class Solution {
    public int sumNums(int n) {
        return (1+n)*n/2;
    }
}

在这里插入图片描述

二、231. 2 的幂

1.题目

231. 2 的幂

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

提示:
-231 <= n <= 231 - 1

2.分析

首先观察几个2的幂次的二进制数:

十进制二进制
10001
20010
40100
81000

可以看出,2的幂次在二进制数表示中,有且只有一位是1,其余都是0。
以 8 为例,如果把该数减 1,7 的二进制数为 0111,那么就会发现:
8 & 7 = 0,二进制运算为:
1000 0111 0000 \begin{array}{r} 1000\\ 0 1 11\\ \hline 0000 \end{array} 100001110000
利用这个特点,就可以转成代码

3.代码

class Solution {
    public boolean isPowerOfTwo(int n) {
        //转成long类型,防止int类型的最小值-2147483648减1时溢出
        long num = n;
        //对0进行特殊判断,因为0 & -1 = 0,但0不是2的幂
        return num != 0 && (num & (num - 1)) == 0;
    }
}

在这里插入图片描述

三、3的幂

1.题目

3的幂

给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3x

提示:
-231 <= n <= 231 - 1

2.分析

3 x = n 3^x = n 3x=n,求 x x x,可以通过对数换底公式求出。

  1. 对数换底公式:(对数公式中,n一定大于0)
    x = l o g 3 n = l o g 10 n l o g 10 3 x=log_3n=\frac{log_{10}n}{log_{10}3} x=log3n=log103log10n
  2. 浮点数的比较:
  • 在浮点数(float、double)的运算中,会出现浮点数运算不精确的问题。
    例如:

    public static void main(String[] args) {
            System.out.println(1-0.9);
        }
    

    结果:

    0.09999999999999998

    又因为 M a t h . p o w ( 3 , i ) Math.pow(3, i) Math.pow(3,i) 方法的返回值是double类型,所以在跟n的比较时,需要用浮点数的比较方式:
    a − b < 某 个 精 度 ( 通 常 用 1 e − 6 到 1 e − 10 , 经 验 值 ) a-b<某个精度(通常用1e-6到1e-10,经验值) ab<1e61e10

3.代码

class Solution {
    public boolean isPowerOfThree(int n) {
        int i = (int) (Math.log10(n) / Math.log10(3));
        return n > 0 && Math.abs(Math.pow(3, i) - n) < 1e-10;
    }
}

在这里插入图片描述

四、342. 4的幂

1.题目

342. 4的幂

给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4x

提示:
-231 <= n <= 231 - 1

2.分析

思路跟第三题一样,主要涉及对数换底公式以及浮点数的判断。

3.代码

class Solution {
    public boolean isPowerOfFour(int n) {
        int i = (int) (Math.log10(n) / Math.log10(4));
        return n > 0 && Math.abs(Math.pow(4, i) - n) < 1e-10;
    }
}

在这里插入图片描述

五、1492. n 的第 k 个因子

1.题目

1492. n 的第 k 个因子

给你两个正整数 n 和 k 。
如果正整数 i 满足 n % i == 0 ,那么我们就说正整数 i 是整数 n 的因子。
考虑整数 n 的所有因子,将它们 升序排列 。请你返回第 k 个因子。如果 n 的因子数少于 k ,请你返回 -1 。

提示:
1 <= k <= n <= 1000

2.分析

  1. 题目给出了 n n n 的范围,才1000,直接遍历。
  2. 定义一个用于计数的变量 c o u n t count count,当 c o u n t count count 计数到与 k k k 相等时,说明当前遍历到的 i i i 就是第 k k k
    个因子,直接返回。
  3. 如果循环结束还没有返回,说明 c o u n t < k count < k count<k,则返回 − 1 -1 1

3.代码

class Solution {
    public int kthFactor(int n, int k) {
        int i,count = 0;
        for (i = 1;i <= n;i++){
            if (n % i == 0){
                count++;
            }
            if (count == k){
                return i;
            }
        }
        return -1;
    }
}

在这里插入图片描述

六、367. 有效的完全平方数

1.题目

367. 有效的完全平方数

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
进阶:不要 使用任何内置的库函数,如 sqrt 。

提示:
1 <= num <= 231 - 1

2.分析

  1. 利用二分查找
  • 我这里二分查找设计的思路是,将 1 1 1 n u m num num 看作是一个数组,那么数组长度就是 n u m num num
  • 例如: n u m = 4 num=4 num=4,判断是不是完全平方数
    1 1 1 开始就相当于一个数组: [ 1 , 2 , 3 , 4 ] [1,2,3,4] [1,2,3,4]
    设定左边指针 l = − 1 l = -1 l=1,右边指针 r = 4 r=4 r=4,所以 m i d = l + ( r − l ) / 2 = − 1 + ( 4 − ( − 1 ) ) / 2 = 1 mid = l + (r - l) / 2=-1+(4-(-1))/2=1 mid=l+(rl)/2=1+(4(1))/2=1
    对于上面的数组来说,下标为 m i d = 1 mid=1 mid=1 位置的元素是 2 2 2,所以计算平方数时要将 m i d + 1 mid+1 mid+1
  • t > n u m t>num t>num,则将右指针 r = m i d r=mid r=mid;当 t < n u m t < num t<num ,则将左指针 l = m i d l=mid l=mid;当 t = n u m t = num t=num,则直接返回 t r u e true true
  1. 因为在计算 ( m i d + 1 ) ∗ ( m i d + 1 ) (mid + 1) * (mid + 1) (mid+1)(mid+1) 时,有可能会溢出,所以方法内部变量用 l o n g long long 类型。

3.代码

class Solution {
    public boolean isPerfectSquare(int num) {
        long l = -1,r = num;
        long mid;
        while (r - l > 1){
            mid = l + (r - l) / 2;
            long t = (mid + 1) * (mid + 1);
            if (t > num){
                r = mid;
            } else if (t < num){
                l = mid;
            } else {
                return true;
            }
        }
        return false;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值