【LeetCode】剪绳子&&和为s的连续正数序列&&圆圈中最后剩下的数字

57.剪绳子

题目:

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

题解:
  • 当绳子长度为2时,由于m>1,因此剪成1和1,返回1;

  • 当绳子长度为3时,剪成2和1,返回2;

  • 当绳子长度为4时,剪成2和2,返回4;

  • 当绳子长度大于4时,将其尽可能多的剪成3,剩下的不剪即可。

public int cuttingRope(int n) {
        if(n == 2)return 1;
        if(n == 3)return 2;
        if(n == 4)return 4;
        int res = 1;
        while(n > 4){
            res *= 3;
            n -= 3;
        }
        return res*n;
    }

58.和为s的连续正数序列

题目:

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

题解:
  • 由于是连续正整数序列且至少包含两个数,因此初始化i = 1,j = 2,sum = 3;
  • 使用双指针i 和 j 进行遍历
    • 遍历结束的条件
      • i == j,二者指向同一个数字不符合题目至少含有两个数,循环结束;
      • 假如i == j 时未跳出循环,以target = 9为例,二者会相继一前一后的向后移动直至二者均指向9,此时返回的res中会多出不符合条件的数组[9];
    • 如果sum == target,则将其转换为int[]类型的array,存入list;
    • 如果sum >= target,先令sum减去i,然后执行i++,使得继续向前遍历;
    • 如果sum < target,先令j++,再执行sum加上 j,继续向前遍历。
  public int[][] findContinuousSequence(int target) {
        List<int[]> res = new ArrayList<>();
        int i = 1, j = 2, sum = 3;
        while (i < j){
            if (sum == target){
                int[] array = new int[j - i + 1];
                int temp = i;
                for (int s = 0; s < array.length; s++){
                    array[s] = temp;
                    temp++;
                }
                res.add(array);
            }
            if (sum >= target){
                sum -= i;
                i++;
            }
            else {
                j++;
                sum += j;
            }
        }
        return res.toArray(new int[0][]);
    }
  • 其中sum ==target部分可优化为
 if(s == target) {
     int[] ans = new int[j - i + 1];
     for(int k = i; k <= j; k++)
         ans[k - i] = k;
     res.add(ans);
  }

59.圆圈中最后剩下的数字

题目:

0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

题解:
  • 将 n 个数字存入list集合;
  • 通过取余操作获得每次需要删除的元素下标;
  • 返回list的第一个元素即可。
 public int lastRemaining(int n, int m) {
         List<Integer> list = new ArrayList<>();
        for (int i = 0; i < n; i++){
            list.add(i);
        }
        int index = (m - 1) % list.size();
        while (list.size() > 1){
            list.remove(index);
            index = (index + m - 1) % list.size();
        }
        return list.get(0);
    }

青年孤愤,中年清高,晚年固执,一事无成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值