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