189. 旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [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:
输入: [-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) {
k=k%nums.size();
reverse(nums.begin(),nums.begin()+nums.size()-k);
reverse(nums.begin()+nums.size()-k,nums.end());
reverse(nums.begin(),nums.end());
}
};
268. 丢失的数字
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
进阶:
你能否实现线性时间复杂度、仅使用额外常数空间的算法解决此问题?
示例 1:
输入:nums = [3,0,1]
输出:2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums 中。
示例 2:
输入:nums = [0,1]
输出:2
解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2 是丢失的数字,因为它没有出现在 nums 中。
示例 3:
输入:nums = [9,6,4,2,3,5,7,0,1]
输出:8
解释:n = 9,因为有 9 个数字,所以所有的数字都在范围 [0,9] 内。8 是丢失的数字,因为它没有出现在 nums 中。
示例 4:
输入:nums = [0]
输出:1
解释:n = 1,因为有 1 个数字,所以所有的数字都在范围 [0,1] 内。1 是丢失的数字,因为它没有出现在 nums 中。
//方法一异或 :把零到n中的所有出现的数字与0-n-1中所有数字相异或
//乘法结合律,每个出现的数字会与0-n-1中的相等数字结合
class Solution {
public:
int missingNumber(vector<int>& nums) {
int temp=nums.size();
for(int i=0;i<nums.size();i++){
temp^=i^nums[i];
}
return temp;
}
};
//利用和
class Solution {
public:
int missingNumber(vector<int>& nums) {
int sum=nums.size();
for(int i=0;i<nums.size();i++){
sum+=i;
sum-=nums[i];
}
return sum;
}
};
136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ret=nums[0];
for(int i=1;i<nums.size();i++){
ret^=nums[i];
}
return ret;
}
};
#518. 金币
题目描述
国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续 N 天每天收到 N 枚金币后,骑士会在之后的连续 N+1 天里,每天收到 N+1 枚金币。
现在给出一个日期 x,求第一天到第 x 天骑士总共获得的金币数。
输入
输入一行一个整数 x。(1≤x≤104)
输出
输出骑士总共获得的金币数。
样例输入
10
样例输出
30
//方法一:二分法
#include<iostream>
using namespace std;
int n;
int l, r;
int bs() {
int l = 1; int r = n;
while (l != r) {
int mid = (l + r + 1) / 2;
int sum = (1 + mid) * mid;
if (2*n >= sum) {
l = mid;
}
else {
r = mid - 1;
}
}
return l;
}
int main() {
int sum = 0;
cin >> n;
int day = bs();
int target = 0;
int temp = (1 + day) * day / 2;
int res = n - temp;
for (int i = 1; i <= day; i++) {
target += i * i;
}
target += res * (day + 1);
cout << target << endl;
}
//方法二:o(n)时间复杂度
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int h=0;
int l = 1 , i , sum = 0;
for( i=1;i<=n;i+=l)
{
sum+=l*l;
l++;
h=i;
}
if(i!=n)
{
sum+=(n-h)*l;
}
cout<<sum;
}
剑指 Offer 56 - I. 数组中数字出现的次数
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int exor = 0;
for (int i : nums) {
exor ^= i; // 求出两个独立数字的异或值
}
int first1 = 1;
while (!(first1 & exor)) {
first1 <<= 1; // 找到该异或值从右往左第一个 1 出现的位置
}
int a = 0, b = 0;
for (int i : nums) {
if (i & first1) {
a ^= i; // 如果 i 从右往左第一个 1 出现的位置与异或值一样
}
else {
b ^= i; // 如果 i 从右往左第一个 1 出现的位置与异或值不一样
}
}
return {a, b};
}
};
#509. 智力大冲浪
题目描述
小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者 m 元。接下来主持人宣布了比赛规则:
首先,比赛时间分为 n 个时段 (n≤500),它又给出了很多小游戏,每个小游戏都必须在规定期限 ti 前完成 (1≤ti≤n)。如果一个游戏没能在规定期限前完成,则要从奖励费 m 元中扣去一部分钱 wi,wi 为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!注意:比赛绝对不会让参赛者赔钱!
输入
第一行为 m,表示一开始奖励给每位参赛者的钱;
第二行为 n,表示有 n 个小游戏;
第三行有 n 个数,分别表示游戏 1 到 n 的规定完成期限;
第四行有 n 个数,分别表示游戏 1 到 n 不能在规定期限前完成的扣款数。
输出
输出小伟能赢取最多的钱。
样例输入
10000
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10
样例输出
9950
//最小堆加贪心算法
#include<iostream>
using namespace std;
#include<queue>
#include<algorithm>
struct node {
int time;
int money;
};
node p[505];
priority_queue<int,vector<int>,greater<int> > que;//最小堆
bool cmp(const node& a, const node& b) {
return a.time < b.time|| (a.time == b.time && a.money <= b.money);
}
int main() {
int m,n;
cin >> m>>n;
int summoney = 0;
for (int i = 0; i < n; i++) {
cin >> p[i].time;
}
for (int i = 0; i < n; i++) {
cin >> p[i].money;
summoney += p[i].money;
}
sort(p, p + n,cmp);
int sum = 0;
int t = 1;
for (int i = 0; i < n; i++) {
if (p[i].time >= t) {
que.push(p[i].money);
t++;
}
else {
if (p[i].money > que.top()) {
que.pop();
que.push(p[i].money);
}
}
}
while (!que.empty()) {
sum += que.top();
que.pop();
}
int d = summoney - sum;
cout << m - d << endl;
}