赞
踩
(若有侵权会及时删除,请联系告知!)
给你一个长度为 n 的整数数组,每次操作将会使 n - 1 个元素增加 1 。返回让数组所有元素相等的最小操作次数。
示例1:
输入:nums = [1,2,3]
输出:3
解释:
只需要3次操作(注意每次操作会增加两个元素的值):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
示例2:
输入:nums = [1,1,1]
输出:0
class Solution {
public:
int minMoves(vector<int>& nums) {
int minValue = *min_element(nums.begin(),nums.end());
int sum = 0;
for(int i = 0; i < nums.size(); i++)
{
sum += (nums[i] - minValue);
}
return sum;
}
};
给你一个长度为 n n n 的整数数组 n u m s nums nums,请你判断在最多改变 1 个元素的情况下,该数组能否变成一个非递减数列。
我们是这样定义一个非递减数列的: 对于数组中任意的 i i i, ( 0 < = i < = n − 2 ) (0 <= i <= n-2) (0<=i<=n−2),总满足 n u m s [ i ] < = n u m s [ i + 1 ] nums[i] <= nums[i + 1] nums[i]<=nums[i+1]。
示例1:
输入: nums = [4,2,3]
输出: true
解释: 你可以通过把第一个 4 变成 1 来使得它成为一个非递减数列。
示例2:
输入: nums = [4,2,1]
输出: false
解释: 你不能在只改变一个元素的情况下将其变为非递减数列。
class Solution { public: bool checkPossibility(vector<int>& nums) { if (nums.size() <= 1) { return true; } int count = 0; for(int i = 1; i < nums.size() && count < 2; i++) { if(nums[i - 1] <= nums[i]) continue; count++; if(i - 2 >= 0 && nums[i - 2] > nums[i]) nums[i] = nums[i - 1]; else nums[i - 1] = nums[i]; } return count <= 1; } };
给定一个数组 n u m s nums nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例2:
输入: nums = [0]
输出: [0]
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int i = 0,j = 0;
for(int i = 0; i < nums.size(); i++)
{
if(nums[i] != 0)
nums[j++] = nums[i];
}
while(j < nums.size())
nums[j++] = 0;
}
};
给你一个整数数组
n
u
m
s
nums
nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组是数组中的一个连续部分。(注意跟子序列区分)
示例1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例2:
输入:nums = [1]
输出:1
示例3:
输入:nums = [5,4,-1,7,8]
输出:23
class Solution { public: int maxSubArray(vector<int>& nums) { int n = nums.size(); int *dp = new int[n]; dp[0] = nums[0]; for(int i = 1; i < nums.size(); i++) { dp[i] = max(nums[i],nums[i] + dp[i - 1]); } int res = -9999999999; for(int i = 0; i < nums.size(); i++) { res = max(res,dp[i]); } return res; } };
给你一个整数数组 nums 。一个子数组
[
n
u
m
s
l
,
n
u
m
s
l
+
1
,
.
.
.
,
n
u
m
s
r
−
1
,
n
u
m
s
r
]
[nums_l, nums_{l+1}, ..., nums_{r-1}, nums_{r}]
[numsl,numsl+1,...,numsr−1,numsr]的和的绝对值为
a
b
s
(
n
u
m
s
l
+
n
u
m
s
l
+
1
+
.
.
.
+
n
u
m
s
r
−
1
+
n
u
m
s
r
)
abs(numsl + numsl+1 + ... + numsr-1 + numsr)
abs(numsl+numsl+1+...+numsr−1+numsr)。
请你找出
n
u
m
s
nums
nums 中和的绝对值最大的任意子数组(可能为空),并返回该最大值 。
a
b
s
(
x
)
abs(x)
abs(x)定义如下:
如果
x
x
x 是负整数,那么
a
b
s
(
x
)
=
−
x
abs(x)= -x
abs(x)=−x。
如果
x
x
x 是非负整数,那么
a
b
s
(
x
)
=
x
abs(x) = x
abs(x)=x。
示例1:
输入:nums = [1,-3,2,3,-4]
输出:5
解释:子数组 [2,3] 和的绝对值最大,为 abs(2+3) = abs(5) = 5 。
示例2:
输入:nums = [2,-5,1,-4,3,-2]
输出:8
解释:子数组 [-5,1,-4] 和的绝对值最大,为 abs(-5+1-4) = abs(-8) = 8 。
class Solution { public: int maxAbsoluteSum(vector<int>& nums) { int n = nums.size(); int *plus_dp = new int[n]; int *minus_dp = new int[n]; //base case plus_dp[0] = nums[0]; minus_dp[0] = nums[0]; for(int i = 1; i < nums.size(); i++) { plus_dp[i] = max(nums[i],nums[i] + plus_dp[i - 1]); minus_dp[i] = min(nums[i], nums[i] + minus_dp[i - 1]); } int res1 = -999999999; int res2 = 9999999999; for(int i = 0; i < nums.size(); i++) { res1 = max(res1,plus_dp[i]); res2 = min(res2,minus_dp[i]); } res1 = abs(res1); res2 = abs(res2); if(res1 >= res2) return res1; else return res2; } };
给定一个整数数组 n u m s nums nums ,将数组中的元素向右轮转 k k k 个位置,其中 k k k 是非负数。
示例1:
输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
示例2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
具体介绍环状替换和数组翻转算法
class Solution { public: void rotate(vector<int>& nums, int k) { int n = nums.size(); k = k % n; int count = gcd(n,k); for(int start = 0; start < count; start++) { int current = start; int prev = nums[start]; do{ int next = (current + k) % n; swap(nums[next],prev); current = next; }while(start != current); } } };
参考美服的翻转算法,原地址
nums = "----->-->"; k =3
result = "-->----->";
reverse "----->-->" we can get "<--<-----"
reverse "<--" we can get "--><-----"
reverse "<-----" we can get "-->----->"
this visualization help me figure it out :)
class Solution { public: void reverse(vector<int>& nums, int start, int end) { while (start < end) { swap(nums[start], nums[end]); start += 1; end -= 1; } } void rotate(vector<int>& nums, int k) { k %= nums.size(); reverse(nums, 0, nums.size() - 1); reverse(nums, 0, k - 1); reverse(nums, k, nums.size() - 1); } };
示例1:
输入: nums = [4,3,2,6]
输出: 26
解释:
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
所以 F(0), F(1), F(2), F(3) 中的最大值是 F(3) = 26 。
示例2:
输入: nums = [100]
输出: 0
-
class Solution { public: int maxRotateFunction(vector<int>& nums) { int n = nums.size(); int sum = 0; int total = 0; //int *dp = new int[n]; int dp_0 = 0; int dp_1 = 0; for(int i = 0; i < n; i++) { total += nums[i]; sum += i * nums[i]; } dp_0 = sum; int maxValue = dp_0; for(int k = 1; k < n; k++) { dp_1 = dp_0 + total - n * nums[n - k]; dp_0 = dp_1; maxValue = max(maxValue,dp_0); //cout << dp[k] << endl; } return maxValue; } };
88. 合并两个有序数组
题目要求算法复杂度为
O
(
m
+
n
)
O(m + n)
O(m+n)
思路一:直接在nums1容器中添加元素,最后进行遍历
思路二:(双指针法)由于nums1与nums2已经被排序,我们可以将两个数组看作队列,每次从两个数组头部取出比较小的数字放到结果中。于是我们分别设置m和n为两个数组的头部指针,实例代码如下:
class Solution { public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { int *ans = new int[m + n]; int i = 0, j = 0,k = 0; while(i < m || j < n) { if(i == m) { ans[k++] = nums2[j++]; } else if(j == n) { ans[k++] = nums1[i++]; } else if(nums1[i] <= nums2[j]) { ans[k++] = nums1[i++]; } else if(nums1[i] > nums2[j]) { ans[k++] = nums2[j++]; } } for(int i = 0; i < m + n; i++) { nums1[i] = ans[i]; } } };
思路三:由于 n u m s 1 nums1 nums1 的后半部分为空,可以直接覆盖而不会影响结果。因此可以指针设置为从后向前遍历,每次取两者之中的较大者放进 n u m s 1 nums1 nums1 的最后面。由于填补一个空格之后又多出来一个空格,因此示例代码如下:
class Solution { public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { int tail = m + n - 1; m--; n--; while(m >= 0 || n >= 0 ) { if(m < 0) { nums1[tail--] = nums2[n--]; } else if(n < 0) { nums1[tail--] = nums1[m--]; } else if(nums1[m] >= nums2[n]) { nums1[tail--] = nums1[m--]; } else if(nums1[m] < nums2[n]) { nums1[tail--] = nums2[n--]; } } } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。