赞
踩
目录
小扣打算给自己的 VS code 安装使用插件,初始状态下带宽每分钟可以完成 1
个插件的下载。假定每分钟选择以下两种策略之一:
请返回小扣完成下载 n
个插件最少需要多少分钟。
注意:实际的下载的插件数量可以超过 n
个
示例 1:
输入:
n = 2
输出:
2
解释: 以下两个方案,都能实现 2 分钟内下载 2 个插件
- 方案一:第一分钟带宽加倍,带宽可每分钟下载 2 个插件;第二分钟下载 2 个插件
- 方案二:第一分钟下载 1 个插件,第二分钟下载 1 个插件
示例 2:
输入:
n = 4
输出:
3
解释: 最少需要 3 分钟可完成 4 个插件的下载,以下是其中一种方案: 第一分钟带宽加倍,带宽可每分钟下载 2 个插件; 第二分钟下载 2 个插件; 第三分钟下载 2 个插件。
提示:
1 <= n <= 10^5
- class Solution {
- public:
- int leastMinutes(int n) {
- int ans = n, r=1,k=0;
- while(r<n){
- r*=2,k+=1,ans=min(ans,(n+r-1)/r+k);
- }
- return ans;
- }
- };
有 N
位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N
道题目,整型数组 questions
中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题,请返回被选的 N
道题目至少包含多少种知识点类型。
示例 1:
输入:
questions = [2,1,6,2]
输出:
1
解释:有 2 位扣友在 4 道题目中选择 2 题。 可选择完成知识点类型为 2 的题目时,此时仅一种知识点类型 因此至少包含 1 种知识点类型。
示例 2:
输入:
questions = [1,5,1,3,4,5,2,5,3,3,8,6]
输出:
2
解释:有 6 位扣友在 12 道题目中选择题目,需要选择 6 题。 选择完成知识点类型为 3、5 的题目,因此至少包含 2 种知识点类型。
提示:
questions.length == 2*n
2 <= questions.length <= 10^5
1 <= questions[i] <= 1000
- class Solution {
- public:
- int halfQuestions(vector<int>& questions) {
- map<int, int>m;
- for (auto x : questions)m[x]++;
- vector<int>v;
- for (auto mi : m)v.push_back(mi.second);
- sort(v.begin(), v.end());
- int s = 0;
- for (int i = v.size() - 1; i >= 0; i--) {
- s += v[i];
- if (s >= questions.size() / 2)return v.size() - i;
- }
- return -1;
- }
- };
实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
示例 1:
输入: s = "leetcode"
输出: false
示例 2:
输入: s = "abc"
输出: true
限制:
0 <= len(s) <= 100
如果你不使用额外的数据结构,会很加分。
- class Solution:
- def isUnique(self, s: str) -> bool:
- s=sorted(s)
- for i in range(1,len(s)):
- if s[i]==s[i-1]:
- return False
- return True
给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。
示例 1:
输入: s1 = "abc", s2 = "bca"
输出: true
示例 2:
输入: s1 = "abc", s2 = "bad"
输出: false
说明:
0 <= len(s1) <= 100
0 <= len(s2) <= 100
- class Solution:
- def CheckPermutation(self, s1: str, s2: str) -> bool:
- s1=sorted(s1)
- s2=sorted(s2)
- return s1==s2
URL化。编写一种方法,将字符串中的空格全部替换为%20。假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的“真实”长度。(注:用Java实现的话,请使用字符数组实现,以便直接在数组上操作。)
示例 1:
输入:"Mr John Smith ", 13
输出:"Mr%20John%20Smith"
示例 2:
输入:" ", 5
输出:"%20%20%20%20%20"
提示:
字符串长度在 [0, 500000] 范围内。
- class Solution:
- def replaceSpaces(self, s: str, length: int) -> str:
- ans=''
- for i in range(len(s)):
- if i>=length:
- break
- if s[i]==' ':
- ans+='%20'
- else:
- ans+=s[i]
- return ans
字符串有三种编辑操作:插入一个英文字符、删除一个英文字符或者替换一个英文字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。
示例 1:
输入: first = "pale" second = "ple" 输出: True
示例 2:
输入: first = "pales" second = "pal" 输出: False
- class Solution {
- public:
- bool oneEditAway(string first, string second) {
- int d=int(first.length())-int(second.length());
- if(d==0)return change(first,second);
- if(d==1)return add(first,second);
- if(d==-1)return add(second,first);
- return false;
- }
- bool add(string first, string second) {
- for(int i=0;i<second.length();i++){
- if(first[i]==second[i])continue;
- for(int j=i;j<second.length();j++){
- if(first[j+1]!=second[j])return false;
- }
- return true;
- }
- return true;
- }
- bool change(string first, string second) {
- int n=0;
- for(int i=0;i<second.length();i++){
- if(first[i]!=second[i])n++;
- if(n>1)return false;
- }
- return true;
- }
- };
字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa
会变为a2b1c5a3
。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。
示例1:
输入:"aabcccccaaa" 输出:"a2b1c5a3"
示例2:
输入:"abbccd" 输出:"abbccd" 解释:"abbccd"压缩后为"a1b2c2d1",比原字符串长度更长。
提示:
- class Solution {
- public:
- string compressString(string s) {
- auto s2=compress(s);
- return s2.length()<s.length()?s2:s;
- }
- string compress(string s) {
- string ans;
- char c=0;
- int n=0;
- for(auto si:s){
- if(si==c)n++;
- else{
- if(n)ans+=c+to_string(n);
- c=si,n=1;
- }
- }
- return ans+c+to_string(n);
- }
- };
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
示例 1:
输入: [ [1,1,1], [1,0,1], [1,1,1] ] 输出: [ [1,0,1], [0,0,0], [1,0,1] ]
示例 2:
输入: [ [0,1,2,0], [3,4,5,2], [1,3,1,5] ] 输出: [ [0,0,0,0], [0,4,5,0], [0,3,1,0] ]
- class Solution {
- public:
- void setZeroes(vector<vector<int>>& matrix) {
- vector<int>r(matrix.size());
- vector<int>c(matrix[0].size());
- for(int i=0;i<matrix.size();i++){
- for(int j=0;j<matrix[0].size();j++){
- if(matrix[i][j]==0)r[i]=1,c[j]=1;
- }
- }
- for(int i=0;i<matrix.size();i++){
- for(int j=0;j<matrix[0].size();j++){
- if(r[i]||c[j])matrix[i][j]=0;
- }
- }
- }
- };
若链表中的某个节点,既不是链表头节点,也不是链表尾节点,则称其为该链表的「中间节点」。
假定已知链表的某一个中间节点,请实现一种算法,将该节点从链表中删除。
例如,传入节点 c
(位于单向链表 a->b->c->d->e->f
中),将其删除后,剩余链表为 a->b->d->e->f
示例:
输入:节点 5 (位于单向链表 4->5->1->9 中) 输出:不返回任何数据,从链表中删除传入的节点 5,使链表变为 4->1->9
- class Solution {
- public:
- void deleteNode(ListNode* node) {
- node->val=node->next->val;
- node->next=node->next->next;
- }
- };
二叉搜索树 二叉搜索树(BST)_csuzhucong的博客-CSDN博客
给定一个32位整数 num
,你可以将一个数位从0变为1。请编写一个程序,找出你能够获得的最长的一串1的长度。
示例 1:
输入: num
= 1775(110111011112)
输出: 8
示例 2:
输入: num
= 7(01112)
输出: 4
- class Solution {
- public:
- int reverseBits(unsigned num) {
- vector<int>v;
- int n=0,ans=0;
- while(num){
- if(num&1)n++;
- else{
- if(n)v.push_back(n),n=0;
- else ans=max(ans,maxLen(v)),v.clear();
- }
- num/=2;
- }
- v.push_back(n);
- return min(32,max(ans,maxLen(v)));
- }
- int maxLen(vector<int>&v){
- if(v.empty())return 1;
- if(v.size()==1)return v[0]+1;
- int ans=0;
- for(int i=1;i<v.size();i++)ans=max(ans,v[i]+v[i-1]+1);
- return ans;
- }
- };
下一个数。给定一个正整数,找出与其二进制表达式中1的个数相同且大小最接近的那两个数(一个略大,一个略小)。
示例1:
输入:num = 2(或者0b10)
输出:[4, 1] 或者([0b100, 0b1])
示例2:
输入:num = 1
输出:[2, -1]
提示:
num的范围在[1, 2147483647]之间;
如果找不到前一个或者后一个满足条件的正数,那么输出 -1。
思路:
nextGreaterElement函数是从 力扣OJ 556. 下一个更大元素 III 略改而成。
只需要改2个地方,一个是十进制改成二进制,一个是二进制字符串前面添0。
nextLesserElement函数是nextGreaterElement函数直接修改得到,代码逻辑是一样的。
- int nextGreaterElement(int n) {
- char sn[40];
- for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
- sn[32]='\0';
- if(!next_permutation(sn,sn+32))return -1;
- long long res = StrToInt(sn,2);
- if(res==int(res))return res;
- return -1;
- }
- int nextLesserElement(int n) {
- char sn[40];
- for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
- sn[32]='\0';
- if(!prev_permutation(sn,sn+32))return -1;
- long long res = StrToInt(sn,2);
- if(res==int(res))return res;
- return -1;
- }
-
- class Solution {
- public:
- vector<int> findClosedNumbers(int num) {
- vector<int> ans(2);
- ans[1]=nextLesserElement(num);
- ans[0]=nextGreaterElement(num);
- return ans;
- }
- };
题目:
绘制直线。有个单色屏幕存储在一个一维数组中,使得32个连续像素可以存放在一个 int 里。屏幕宽度为w,且w可被32整除(即一个 int 不会分布在两行上),屏幕高度可由数组长度及屏幕宽度推算得出。请实现一个函数,绘制从点(x1, y)到点(x2, y)的水平线。
给出数组的长度 length,宽度 w(以比特为单位)、直线开始位置 x1(比特为单位)、直线结束位置 x2(比特为单位)、直线所在行数 y。返回绘制过后的数组。
示例1:
输入:length = 1, w = 32, x1 = 30, x2 = 31, y = 0
输出:[3]
说明:在第0行的第30位到第31为画一条直线,屏幕表示为[0b000000000000000000000000000000011]
示例2:
输入:length = 3, w = 96, x1 = 0, x2 = 95, y = 0
输出:[-1, -1, -1]
代码:
- class Solution {
- public:
- vector<int> drawLine(int length, int w, int x1, int x2, int y) {
- vector<int>ans;
- int s=x1/32+w/32*y,e=x2/32+w/32*y;
- for(int i=0;i<s;i++)ans.insert(ans.end(),0);
- for(int i=s;i<=e;i++)ans.insert(ans.end(),-1);
- for(int i=e+1;i<length;i++)ans.insert(ans.end(),0);
- x1=32-x1%32,x2=31-x2%32;
- long long a=1;
- ans[s]&=int((a<<x1)-1),ans[e]&=(-(1<<x2));
- return ans;
- }
- };
三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。
示例1:
输入:n = 3 输出:4 说明: 有四种走法
示例2:
输入:n = 5 输出:13
提示:
- class Solution {
- public:
- int waysToStep(int n) {
- vector<int>v(n+10);
- v[0]=1,v[1]=1,v[2]=2,v[3]=4;
- for(int i=4;i<=n;i++)v[i]=((v[i-1]+v[i-2])%1000000007+v[i-3])%1000000007;
- return v[n];
- }
- };
幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
- class Solution {
- public:
- vector<vector<int>> subsets(vector<int>& nums) {
- return GetAllSubsets(nums,false);
- }
- };
硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)
示例1:
输入: n = 5 输出:2 解释: 有两种方式可以凑成总金额: 5=5 5=1+1+1+1+1
示例2:
输入: n = 10 输出:4 解释: 有四种方式可以凑成总金额: 10=10 10=5+5 10=5+1+1+1+1+1 10=1+1+1+1+1+1+1+1+1+1
说明:
注意:
你可以假设:
- class Solution {
- public:
- int waysToChange(int n) {
- vector<int>coins{ 25,10,5,1 };
- return DP_CoinCombine(coins, n, 1000000007);
- }
- };
给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。
初始化 A 和 B 的元素数量分别为 m 和 n。
示例:
输入: A = [1,2,3,0,0,0], m = 3 B = [2,5,6], n = 3 输出: [1,2,2,3,5,6]
说明:
A.length == n + m
- class Solution {
- public:
- void merge(vector<int>& A, int m, vector<int>& B, int n) {
- for(int i=0;i<n;i++)A[i+m]=B[i];
- sort(A.begin(),A.end());
- }
- };
搜索旋转数组。给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次了,次数不详。请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的。若有多个相同元素,返回索引值最小的一个。
示例1:
输入: arr = [15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14], target = 5
输出: 8(元素5在该数组中的索引)
示例2:
输入:arr = [15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14], target = 11
输出:-1 (没有找到)
提示:
arr 长度范围在[1, 1000000]之间
- class Solution {
- public:
- int search(vector<int>& nums, int target) {
- for(int i=0;i<nums.size();i++)if(nums[i]==target)return i;
- return -1;
- }
- };
设计一个算法,算出 n 阶乘有多少个尾随零。
示例 1:
输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。
示例 2:
输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.
说明: 你算法的时间复杂度应为 O(log n) 。
- class Solution {
- public:
- int trailingZeroes(int n) {
- if (n < 5)return 0;
- return n / 5 + trailingZeroes(n / 5);
- }
- };
编写一个方法,找出两个数字a
和b
中最大的那一个。不得使用if-else或其他比较运算符。
示例:
输入: a = 1, b = 2 输出: 2
- class Solution {
- public:
- int maximum(int a, int b) {
- long long c=a;
- int flag=(unsigned long long)(c-b)>>63;
- return a+(b-c)*flag;
- }
- };
给定一个整数数组,编写一个函数,找出索引m
和n
,只要将索引区间[m,n]
的元素排好序,整个数组就是有序的。注意:n-m
尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n]
,若不存在这样的m
和n
(例如整个数组是有序的),请返回[-1,-1]
。
示例:
输入: [1,2,4,7,10,11,7,12,6,7,16,18,19] 输出: [3,9]
提示:
0 <= len(array) <= 1000000
- class Solution {
- public:
- vector<int> subSort(vector<int>& array) {
- vector<int>v=array;
- sort(v.begin(),v.end());
- int low=0,high=v.size()-1;
- while(low <v.size() && v[low]==array[low])low++;
- if(low==v.size())return vector<int>{-1,-1};
- while(low <high && v[high]==array[high])high--;
- return vector<int>{low,high};
- }
- };
给定一个整数数组,找出总和最大的连续数列,并返回总和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
- class Solution {
- public:
- int maxSubArray(vector<int>& nums) {
- return DP_MaxSubArray::maxSubArray(nums);
- }
- };
在老式手机上,用户通过数字键盘输入,手机将提供与这些数字相匹配的单词列表。每个数字映射到0至4个字母。给定一个数字序列,实现一个算法来返回匹配单词的列表。你会得到一张含有有效单词的列表。映射如下图所示:
示例 1:
输入: num = "8733", words = ["tree", "used"] 输出: ["tree", "used"]
示例 2:
输入: num = "2", words = ["a", "b", "c", "d"] 输出: ["a", "b", "c"]
提示:
num.length <= 1000
words.length <= 500
words[i].length == num.length
num
中不会出现 0, 1 这两个数字- class Solution {
- public:
- vector<string> getValidT9Words(string num, vector<string>& words) {
- vector<string>ans;
- for(auto s:words){
- if (trans(s) == num)ans.push_back(s);
- }
- return ans;
- }
- string trans(string s) {
- string ans = "";
- for (auto c : s)ans += trans(c);
- return ans;
- }
- char trans(char c) {
- if (c == 's')return '7';
- if (c == 'v')return '8';
- if (c > 'v')return '9';
- char x = '2';
- return x + (c - 'a') / 3;
- }
- };
给定两个整数数组,请交换一对数值(每个数组中取一个数值),使得两个数组所有元素的和相等。
返回一个数组,第一个元素是第一个数组中要交换的元素,第二个元素是第二个数组中要交换的元素。若有多个答案,返回任意一个均可。若无满足条件的数值,返回空数组。
示例:
输入: array1 = [4, 1, 2, 1, 1, 2], array2 = [3, 6, 3, 3] 输出: [1, 3]
示例:
输入: array1 = [1, 2, 3], array2 = [4, 5, 6]
输出: []
提示:
1 <= array1.length, array2.length <= 100000
- class Solution {
- public:
- vector<int> findSwapValues(vector<int>& array1, vector<int>& array2) {
- int d = 0;
- set<int>s;
- for (auto x : array1)d += x, s.insert(x);
- for (auto x : array2)d -= x;
- if (d & 1)return vector<int>{};
- d /= 2;
- for (auto x : array2) {
- if (s.find(x + d) != s.end())return vector<int>{x + d, x};
- }
- return vector<int>{};
- }
- };
设计一个函数把两个数字相加。不得使用 + 或者其他算术运算符。
示例:
输入: a = 1, b = 1 输出: 2
提示:
a
, b
均可能是负数或 0- class Solution {
- public:
- int add(unsigned a, unsigned b) {
- int x=1,s=0,flag=0;
- while(true){
- int a2=a&x;
- int b2=b&x;
- if(!a2&&!b2){
- if(flag)s^=x;
- flag=0;
- }else if(a2&&b2){
- if(flag)s^=x;
- flag=1;
- }else{
- if(!flag)s^=x,flag=0;
- }
- if(x==(1<<31))break;
- x=x<<1;
- }
- return s;
- }
- };
给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。
返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。
示例 1:
输入: ["A","1","B","C","D","2","3","4","E","5","F","G","6","7","H","I","J","K","L","M"] 输出: ["A","1","B","C","D","2","3","4","E","5","F","G","6","7"]
示例 2:
输入: ["A","A"] 输出: []
提示:
array.length <= 100000
- class Solution {
- public:
- vector<string> findLongestSubarray(vector<string>& array) {
- map<int,int>m;
- m[0]=-1;
- int dif=0,low=0,high=0;
- for(int i=0;i<array.size();i++){
- if(array[i][0]>='0'&&array[i][0]<='9')dif++;
- else dif--;
- if(m.find(dif)==m.end())m[dif]=i;
- if(i-m[dif]>high-low)low=m[dif],high=i;
- }
- vector<string>ans;
- if(high)for(int i=low+1;i<=high;i++)ans.push_back(array[i]);
- return ans;
- }
- };
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4 输出: [1,2,3,4]
提示:
0 <= len(arr) <= 100000
0 <= k <= min(100000, len(arr))
- class Solution {
- public:
- vector<int> smallestK(vector<int>& arr, int k) {
- sort(arr.begin(),arr.end());
- arr.resize(k);
- return arr;
- }
- };
两个(具有不同单词的)文档的交集(intersection)中元素的个数除以并集(union)中元素的个数,就是这两个文档的相似度。例如,{1, 5, 3} 和 {1, 7, 2, 3} 的相似度是 0.4,其中,交集的元素有 2 个,并集的元素有 5 个。给定一系列的长篇文档,每个文档元素各不相同,并与一个 ID 相关联。它们的相似度非常“稀疏”,也就是说任选 2 个文档,相似度都很接近 0。请设计一个算法返回每对文档的 ID 及其相似度。只需输出相似度大于 0 的组合。请忽略空文档。为简单起见,可以假定每个文档由一个含有不同整数的数组表示。
输入为一个二维数组 docs
,docs[i]
表示 id 为 i
的文档。返回一个数组,其中每个元素是一个字符串,代表每对相似度大于 0 的文档,其格式为 {id1},{id2}: {similarity}
,其中 id1
为两个文档中较小的 id,similarity
为相似度,精确到小数点后 4 位。以任意顺序返回数组均可。
示例:
输入:
- [
- [14, 15, 100, 9, 3],
- [32, 1, 9, 3, 5],
- [15, 29, 2, 6, 8, 7],
- [7, 10]
- ]
输出:
[
"0,1: 0.2500",
"0,2: 0.1000",
"2,3: 0.1429"
]
提示:
docs.length <= 500
docs[i].length <= 500
- class Solution {
- public:
- vector<string> computeSimilarities(vector<vector<int>>& docs) {
- for (auto &vi : docs) {
- sort(vi.begin(), vi.end());
- }
- vector<string>ans;
- for (int i = 0; i < docs.size(); i++) {
- for (int j = i + 1; j < docs.size(); j++) {
- double x = simi(docs[i], docs[j]);
- std::stringstream stream{};
- stream << std::fixed << std::setprecision(4) << int(x * 10000 + 0.5) / 10000.0;
- if (x)ans.push_back(to_string(i) + "," + to_string(j) + ": " + stream.str());
- }
- }
- return ans;
- }
- double simi(vector<int>&v1, vector<int>&v2) {
- if (v1.empty() || v2.empty())return 0;
- int n = 0;
- for (int i = 0, j = 0; i < v1.size() && j < v2.size();) {
- if (v1[i] < v2[j])i++;
- else if (v1[i] > v2[j])j++;
- else n++, i++, j++;
- }
- return n * 1.0 / (v1.size() + v2.size() - n);
- }
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。