力扣面试150(7/150)
6.30 189. 轮转数组
给定一个整数数组 nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
**我的思路:**把nums[0]的数字放在nums[i]上面,把nums[i]的数字放在nums[0]上面
我的代码:
function rotate(nums: number[], k: number): void {let len = nums.length;let time = 0 ; while(time < k){// 把第一个作为放置数字的地方// 遍历数组for(let i = 1 ; i < len ; i++){// 把nums[0]的数字放在nums[i]上面,把nums[i]的数字放在nums[0]上面let temp = nums[i];nums[i] = nums[0];nums[0] = temp;}time ++;}
};
超出时间限制(内心骂了一万次)
这种方法的时间复杂度是O(n*k),当k较大时会导致时间超限。
官方解答:
-
三次反转法:这是最常用的方法,时间复杂度为O(n),空间复杂度为O(1)。
function rotate(nums: number[], k: number): void {let len = nums.length;k = k % len; // 处理k大于数组长度的情况if (k === 0) return; // 如果k为0,直接返回fanzhuan(nums, 0, len - 1); // 翻转整个数组fanzhuan(nums, 0, k - 1); // 翻转前k个元素fanzhuan(nums, k, len - 1); // 翻转剩下的元素 }function fanzhuan(nums: number[], start: number, end: number): void {while (start < end) {let temp = nums[start];nums[start] = nums[end];nums[end] = temp;start++;end--;} }
-
使用额外数组:时间复杂度O(n),空间复杂度O(n)。
哈哈,js里面如果赋值给nums,会新生成一个数组呢,对原数组没有影响
**总结:**虽然自己的想法时间有点超限,但是已经很好啦!多学学一些其他高校的算法
三次轮转法适用的地方:原地旋转、旋转步数较大、适用于任意旋转步数适、用于任何顺序的数组
6.30 121. 买卖股票的最佳时机
给定一个数组 prices
,它的第 i
个元素 prices[i]
表示一支给定股票第 i
天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0
。
我的思路:
如果是暴力的话,先去找最小的价格,然后再最小的价格后面找最大的价格,两个价格相减
思路:动态地处理max:
因为max必须是大的减去小的,所以先设定一个min为prices[0],遍历价格数组,如果遇到比
min还小的就要更新min,如果是比min大的就要更新max
我的代码:
function maxProfit(prices: number[]): number {let min = prices[0] ; let max = 0 ;let i = 1 ; // 第一遍循环找到最小的价格for(i ; i < prices.length ; i++){if(prices[i] < min){min = prices[i];}else {max = max > prices[i] - min ? max : prices[i] - min;}}return max ;
};
总结:代码通过一次遍历数组,不断跟踪最低价格,并计算当天价格与最低价格的差值来更新最大利润。这是一种贪心算法的应用,思路清晰,时间复杂度是O(n),非常高效。