题意:
给定一个整数数组
nums
,将数组中的元素向右轮转k
个位置,其中k
是非负数。
【输入样例】
nums = [1,2,3,4,5,6,7],k=3
【输出样例】
[5,6,7,1,2,3,4]
解题思路1:
直接暴力创建一个新的数组,通过寻找下标的转换规律将轮状后的数组存入临时数组,再将值赋给原数组,因为题目中没有要求返回值,判断的标准还是原数组的最终结果。注意:临时数组跟原数组的下标关系是nums1[i+k] = nums[i],这边需要判断是否超出nums.length-1
class Solution {
public void rotate(int[] nums, int k) {
//暴力解法,直接新建一个数组
int[] nums1 = new int[nums.length];
int j;
for(int i = 0;i< nums.length;++i){
j = i + k;
if(j > nums.length-1) j %= nums.length;
nums1[j] = nums[i];
}
for(int x=0;x
时间: 击败了61.17%
内存: 击败了94.69%
解题思路2. 每次空出数组的最后一位,数组中所有程序往右边挪一个,但是这种情况当k比较大时,会出现超时的情况,仅供看看
class Solution {
public void rotate(int[] nums, int k) {
//每次空出数组的最后一位,进行挪值,这种情况会出现超时,时间复杂度是O(K*nums.length)
int temp;//用来保留每一轮中数组的最后一位
while(k>0){
int endIndex = nums.length - 1;
temp = nums[endIndex];
while(endIndex>0){
nums[endIndex] = nums[endIndex-1];
--endIndex;
}
nums[0] = temp;
--k;
}
}
}
解题思路3. 环状替换解法
1.指针current指向当前要替换的数据,根据下标关系(参考解法1)找到目标位置(next),next指针指向的数据存储在临时变量temp中,之后将指针current指向的数据存储到next位置;
2. 修改current指针,指向next,循环执行1,指导current指针指向start;
3.此时证明出现环状,start指针向后挪一位,循环1,2;
4.循环过程中定义一个count变量,统计已经有多少个数据交换过。
class Solution {
public void rotate(int[] nums, int k) {
//环状替换
int count = 0;
int current = 0;
int start = 0;
int length = nums.length;
while(count
时间: 击败了61.17%
内存: 击败了48.46%(哦吼,还不如新建一个数组哈哈哈)
题意:
给定一个数组
prices
,它的第i
个元素prices[i]
表示一支给定股票第i
天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回
0
。
【输入样例】
[7,1,5,3,6,4]
【输出样例】
5
解题思路1:直接暴力枚举,然后不出意外的超时了~
class Solution {
public int maxProfit(int[] prices) {
//直接暴力枚举,会超时哈哈哈哈哈!!!!
int maxPro = 0;
int buy;
int proTemp;
for(int i=0;i0 && proTemp > maxPro){
maxPro = proTemp;
}
}
}
return maxPro;
}
}
解题思路2:动态规划~
1.设置一个变量minPri,存储前i天中的历史局部最小价格
2. 定义一个变量maxPri,存储能获得的最大利润
3. 假设第i天卖出股票,那其购买时间肯定在[0,i-1]天中,因此,计算price[i]与minPri之间的差值,如果大于maxPri,重新赋值maxPri,否则继续往下寻找更合适的卖出时间
class Solution {
public int maxProfit(int[] prices) {
//动态规划
int maxPri = 0;
int minPri = Integer.MAX_VALUE;
for(int i=0;i maxPri){
maxPri = prices[i] - minPri;
}
}
return maxPri;
}
}
时间: 击败了100.00%
内存: 击败了38.73%
题意:
给你一个整数数组
prices
,其中prices[i]
表示某支股票第i
天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
【输入样例】
[7,1,5,3,6,4]
【输出样例】
7
1买入,5卖出,收入4;3买入,6卖出;收入3
解题思路1:贪心一下,有利润就出售
class Solution {
public int maxProfit(int[] prices) {
//贪心一下
int maxPro = 0;
int len = prices.length;
for(int i=1;i
时间: 击败了72.35%
内存: 击败了43.65%
解题思路2:动态规划(参考官方,我太菜了)
1.矩阵dp[i][0]表示第i天交易后手里没有股票的最大利润,dp[i][1]表示第i天交易后手机还有一只股票的最大利润;
2.dp[i][0]的可能是前一天就没有股票dp[i-1][0],也可能是前一天有股票,然后今天卖出dp[i-1][1]+prices[i];为了收益最大化,去最值;
3.dp[i][1]可能是前一天手上就有一只股票了dp[i-1][1],也可能是前一天还没有股票,今天刚买入dp[i-1][0]-prices[i],减是因为需要花钱购买。
class Solution {
public int maxProfit(int[] prices) {
//贪心一下
int len = prices.length;
int[][] dp = new int[len][2];
dp[0][0] = 0;//今天没有股票
dp[0][1] = -prices[0];//今天买了一直股票,需要支出prices[0]
//虽然不计算亏损多少钱,但是这里dp[0][1]需要存储买了股票的价格是为了后面计算,第i天卖出能获得的最大利润究竟是0(亏损或者没收入)还是有收入
for(int i=1;i<= len-1;++i){
dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
return dp[len-1][0];//最后一天手上肯定是没有股票了
}
}
时间: 击败了29.18%
内存: 击败了65.59%
题意:
给你一个非负整数数组
nums
,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回
true
;否则,返回false
。
【输入样例】
[2,3,1,1,4]
【输出样例】
true
解题思路1:递归,反向扫描数组,找到第一个能一步跳到数组末尾的下标
class Solution {
public boolean canJump(int[] nums) {
if(nums == null || nums.length == 0){
return true;
}
return findJump(nums,nums.length-1);
}
boolean findJump(int nums[],int end){
if(end == 0){
//当跳到下标为0时,表示一条路径被找到
return true;
}
int current = 0;//反向扫描数组,找到第一个能一步跳到数组末尾的下标
for(int i=end -1;i>=0;--i){
if(i + nums[i] >= end){
//yeah,找到啦,我去找正向扫描数组,找到第一个能一步跳到i的下标啦
current = i;
return findJump(nums,current);
}
}
return false;
}
}
时间: 击败了22.10%
内存: 击败了39.84%
解题思路2:贪心算法,感觉思路与递归类似,正向遍历数组中的每一个位置,并实时维护最远可以到达的位置,在遍历的过程中,如果最远可以到达的位置大于等于数组中的最后一个位置,那说明可到达,返回true;若是遍历结束后最后一个位置仍不可到达,则返回false。
class Solution {
public boolean canJump(int[] nums) {
if(nums == null || nums.length == 0){
return true;
}
int len = nums.length;
int maxRight = 0;
for(int i=0;i= len - 1){
return true;
}
}
}
return false;
}
}
时间: 击败了91.57%
内存: 击败了6.11%
题意:
给定一个长度为
n
的 0 索引整数数组nums
。初始位置为nums[0]
。每个元素
nums[i]
表示从索引i
向前跳转的最大长度。换句话说,如果你在nums[i]
处,你可以跳转到任意nums[i + j]
处:
0 <= j <= nums[i]
i + j < n
返回到达
nums[n - 1]
的最小跳跃次数。生成的测试用例可以到达nums[n - 1]
。
【输入样例】
[2,3,1,1,4]
【输出样例】
2
解题思路:生成的测试用例一定能到达nums[n-1],所以不存在不能到达的问题,由于要寻找最小跳跃次数,所以每次贪心一点,步子迈最大。
class Solution {
public int jump(int[] nums) {
//贪心点好啊
int len = nums.length;
int end = 0;
int maxPosition = 0;//当前能到达的最大下标是哪一个
int count = 0;
for(int i = 0; i < len - 1; ++i){
maxPosition = Math.max(maxPosition,i+nums[i]);
if(i == end){
end = maxPosition;
++count;
}
}
return count;
}
}
时间: 击败了98.79%
内存: 击败了39.59%