每日十道算法

1、爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

 

时间复杂度:$O(n)
空间复杂度:$O(n) 

class Solution {
    public int climbStairs(int n) {
        if(n <= 2){
            return n;
        }
        // 爬过n阶的方法
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        for(int i = 3;i < dp.length;i++){
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

2、使用最小花费爬楼梯

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬
需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台
阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

时间复杂度:$O(n)
空间复杂度:$O(n) 

class Main {
    public int main(int[] cost) {
        if(cost == null || cost.length == 0){
            return 0;
        } 
        if(cost.length == 1){
            return cost[0];
        }
        // 爬过第i层楼梯的最小花费
        int[]dp = new int[cost.length];
        dp[0] = cost[0];
        dp[1] = cost[1];
        for(int i = 2;i < cost.length;i++){
            dp[i] = Math.min(dp[i - 1],dp[i - 2]) + cost[i];
        }
        return Math.min(dp[dp.length - 1],dp[dp.length - 2]);
    }
}

 3、搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。
如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
nums 为无重复元素的升序排列数组
请必须使用时间复杂度为 O(log n) 的算法。

 

时间复杂度:$O(log n)
空间复杂度:$O(1)

class Main {
    public int main(int[] nums, int target) {
        if(nums.length == 0 || nums == null){
            return -1;
        }
        int left = 0;
        int right = nums.length - 1;
        int mid = 0;
        while(left <= right){
            mid = left + (right - left) / 2;
            if(nums[mid] == target){
                return mid;
            }
            if(nums[mid] < target){
                left = mid + 1;
            }
            if(nums[mid] > target){
                right = mid - 1;
            }
        }

        if(nums[mid] < target){
            return mid + 1;
        }else{
            return mid;
        }
    }
}

4、二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 
target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回
下标,否则返回 -1。

 

时间复杂度:$O(logn)
空间复杂度:$O(1) 

class Solution {
    public int search(int[] nums, int target) {
        if (nums.length == 0 || nums == null || target < nums[0]){
            return -1;
        }
        int left = 0;
        int right = nums.length - 1;
        while (left <= right){
            int mid = left + (right - left) / 2;
            if (nums[mid] == target){
                return mid;
            }
            if (nums[mid] < target){
                left = mid + 1;
            }
            if (nums[mid] > target){
                right = mid - 1;
            }
        }
        return -1;
    }

}

 5、x 的平方根

 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

 

时间复杂度:$O(log n)
空间复杂度:$O(1)

class Solution {
    public int mySqrt(int x) {
        int left = 0;
        int right = x;
        int res = -1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (mid * mid == x){
                res = mid;
                return res;
            }else if ((long)mid * mid < x){
                res = mid;
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }
        return res;
    }

}

 6、有效的完全平方数

 给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,
则返回 true ,否则返回 false 。

进阶:不要 使用任何内置的库函数,如  sqrt 。

 

时间复杂度:$O(log n)
空间复杂度:$O(1) 

class Main {
    public boolean main(int num) {
        if(num < 0){
            return false;
        }
        int left = 0;
        int right = num;
        while(left <= right){
            int mid = left + (right - left) / 2;
            if(mid * mid == num){
                return true;
            }else if((long)mid * mid > num){
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        return false;
    }
}

7、不用加减乘除做加法

写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则
运算符号。

 

class Main {
    public int main(int a, int b) {
        while(b != 0){ // 当进位为0时退出
            int carry = (a & b) << 1; // c = 进位
            a = a ^ b; // a = 非进位和
            b = carry; // b = 进位
        }
        return a;
    }
}

 8、加一

 给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上
加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

 

时间复杂度:$O(n)
空间复杂度:$O(1) 

 

class Solution {
    public int[] plusOne(int[] digits) {
        for(int i = digits.length - 1; i >= 0; i--){
            if(digits[i] == 9){
                digits[i] = 0;
            }else{
                digits[i] += 1;
                return digits;
            }
        }
        
        //如果所有位都是进位,则长度+1
        digits = new int[digits.length + 1];
        digits[0] = 1;
        return digits;
    }
}

 9、求1+2+…+n

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

class Solution {
    public int sumNums(int n) {
        boolean x = n > 1 && (n +=sumNums(n - 1))> 0;
        return n;
    }
}

10、构建乘积数组

给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中
B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 
B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。

 

时间复杂度:$O(n)
空间复杂度:$O(n) 

class Solution {
    public int[] constructArr(int[] a) {
        if(a.length == 0){
            return new int[0];
        }
        int[] b = new int[a.length];
        b[0] = 1;
        int tmp = 1;
        for(int i = 1; i < a.length; i++){
            b[i] = b[i - 1] * a[i - 1];
        }
        for(int i = a.length - 2; i >= 0; i--){
            tmp *= a[i + 1];
            b[i] *= tmp;
        }
        return b;
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zpeien

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

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

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

打赏作者

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

抵扣说明:

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

余额充值