剑指 offer day24-25

剑指 Offer 14- I. 剪绳子

题目:

给你一根长度为 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。

题解:

贪心思想/清晰图解

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

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

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

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;
    }

剑指 Offer 62. 圆圈中最后剩下的数字

题目:

0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

题解:

1.将数据存储在list集合中,并将上一次删除元素的下标记作index;

2.通过查找规律发现 index=(index+m-1)%list.size();

3.循环执行remove操作,直到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);
    }

剑指 Offer 29. 顺时针打印矩阵

题目:

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

题解:

1.定义变量:

  • direction:其中0代表向右,1代表向下,2代表向左,3代表向上;
  • a、b:(a,b)作为当前位置,并初始化为(0,0)

2.方向的改变:

  • 假如此时前进方向为右,若此时已经到达最右侧或者右边的位置已经被访问则此时需要改变方向,由向右改为向下;
  • 假如此时前进方向为下,若此时已经到达最下侧或者下边的位置已经被访问则此时需要改变方向,由向下改为向左;
  • …同理

3.位置的改变:

  • 如果方向向右,则执行b++;
  • 如果方向向下,则执行a++;
  • 如果方向向左,则执行b- -;
  • 如果方向向上,则执行a- -;
    public int[] spiralOrder(int[][] matrix) {

        if (matrix.length==0){
            return new int[0];
        }
        // //定义前进方向direction:其中0代表向右,1代表向下,2代表向左,3代表向上
        int direction = 0;//初始位置为(0,0),初始方向为右
        int quantity = matrix.length*matrix[0].length;
        int[] res = new int[quantity];//返回的输出数组
        int a = 0,b = 0;//定义初始的横纵坐标
        for (int i=0;i<quantity;i++){
            res[i] = matrix[a][b];
            matrix[a][b]=Integer.MAX_VALUE;//将其定义为最大值,代表已经被访问
            //如果方向向右,当此时已经到达边界或者右侧已经被访问过
            if (direction==0&&(b==matrix[0].length-1||matrix[a][b+1]==Integer.MAX_VALUE)){
                direction=1;
            }else if (direction==1&&(a==matrix.length-1||matrix[a+1][b]==Integer.MAX_VALUE)){
                direction=2;
            }else if (direction==2&&(b==0||matrix[a][b-1]==Integer.MAX_VALUE)){
                direction=3;
            }else if (direction==3&&(a==0||matrix[a-1][b]==Integer.MAX_VALUE)){
                direction=0;
            }

            if (direction==0){
                b++;
            }else if (direction==1){
                a++;
            }else if (direction==2){
                b--;
            }else if (direction==3){
                a--;
            }
        }
        return res;
    }

剑指 Offer 31. 栈的压入、弹出序列

题目:

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。

题解:

1.借助辅助栈stack

  • 首先将pushed[0]压栈;
  • 判断此时栈顶元素是否和poped的元素值是否相等,若相等则进行弹栈操作,反之继续压栈
  • 注意: 在不断的进行弹栈的过程中,一定记得判断此时栈是否为空,只有在不为空的前提下才可以执行stack.peek()操作

2.如果最后栈为空,则返回true。

 public boolean validateStackSequences(int[] pushed, int[] popped) {

        Stack<Integer> stack = new Stack<>();
        int j=0;//记录poped下标
        for (int i=0;i<pushed.length;i++){
            stack.push(pushed[i]);
            //注意判断栈不为空才可以执行stack.ppek()语句
            while (!stack.isEmpty()&&stack.peek()==popped[j]){
                stack.pop();
                j++;
            }
        }
        if(stack.isEmpty()){
            return true;
        }else return false;
    }

听说神不能无处不在,所以创造了妈妈

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值