编程日记,尽量保证每天至少3道leetcode题,仅此记录学习的一些题目答案与思路,尽量用多种思路来分析解决问题,不足之处还望指出。标红题为之后还需要再看的题目。
Total Accepted: 78800 Total Submissions: 361387 Difficulty: Easy
Rotate an array of n elements to the right by k steps.
For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].
Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
题意:整型数组右移k位问题。
思路:
1、另外建立一个复制的数组用来保存原数组,然后找到变换的规律是变换后的第i+k位就是原本的第i位。
代码:
C++
class Solution {
public:
void rotate(vector<int>& nums, int k)
{
if(k==0 || nums.size()<0) return;
int len = nums.size();
vector<int> copy(nums);
// for(int i=0;i<len;i++)
// copy[i] = nums[i];
for(int i=0;i<len;i++)
nums[(i+k)%len] = copy[i];
}
};
结果:24ms
2、一个一个数字去找变换后的位置。比如[1,2,3,4,5,6,7],从1开始,1右移三位,同时保留1将放在的位置。变成[1,2,3,1,5,6,7] tmp = 4,然后再找4移动之后的位置,变成[1,2,3,1,5,6,4] tmp = 7,循环n次结束。
这里需要特别注意就是循环了又绕回来的死循环,需要自加跳出循环。
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k %=n;
if(k==0) return;
int save = nums[0];
int start =0;
int change = start;
int totNums = 0;
while(totNums<n)
{
do{
change= (change+k)%n;
int tmp = nums[change];
nums[change] = save;
save = tmp;
totNums++;
}while(change!=start);
start++;
change = start;
save = nums[change];
}
}
};
结果:24ms
3、先分别交换前k个元素和后n-k个元素,最后交换所有元素。
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k %=n;
if(k<=0 || n<=1) return;
for(int i=0,j=n-k-1;i<j;i++,j--)
swap(nums[i],nums[j]);
for(int i=n-k,j=n-1;i<j;i++,j--)
swap(nums[i],nums[j]);
for(int i=0,j=n-1;i<j;i++,j--)
swap(nums[i],nums[j]);
}
};
结果:28ms
4、
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
if(k<=0 || n<=1) return;
int range = 0;
for (; k = k%n; n -= k, range += k)
{
for (int i = range; i < range+k; i++)
{
swap(nums[i], nums[n - k + i]);
}
}
}
};
结果:24ms
5、分成两部分来看
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
if ((n == 0) || (k <= 0) || (k%n == 0))
{
return;
}
k = k%n;
int start = 0;
int tmp = 0;
//首先将整个数组看成两部分,左边的长度为n-k,右边的长度为k。右边长度应该放在前k个位置。
//这个时候有两种情况,第一种情况是左边部分比右边部分多,这个时候直接将n-k个元素和前k个元素交换一次,这样前k个元素排列好了,
//此时问题的规模n变成了n-k;剩下问题直接转换为在n-k个大小的数组中右移k位。
while (k > 0)
{
if (n - k >= k)
{
for (int i = 0; i < k; i++)
{
tmp = nums[start + n - 2*k + i];
nums[start + n - 2*k + i] = nums[start + n - k + i];
nums[start + n - k + i] = tmp;
}
n = n - k;
k = k%n;
}
else
{
// 如果左边的长度更短,显然不能直接交换前k个元素与后k个元素,但是我们知道倒数第k个元素是第一个元素,因此我们可以先做
//n-k次交换,这个时候前n-k个元素已经排好序了,问题的规模变成了后k个,后面的数只需要再右移动n-k次就行了,起始位置为n-k。
for (int i = 0; i < n - k; i++)
{
tmp = nums[start + i];
nums[start + i] = nums[start + n - k + i];
nums[start + n - k + i] = tmp;
}
tmp = n - k;
n = k;
k -= tmp;
start += tmp;
}
}
}
};
结果:27ms
Compare two version numbers version1 and version2.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.
You may assume that the version strings are non-empty and contain only digits and the . character.
The . character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5 is not “two and a half” or “half way to version three”, it is the fifth second-level revision of the second first-level revision.
Here is an example of version numbers ordering:
0.1 < 1.1 < 1.2 < 13.37
题意:比较版本号的新旧。
思路:
1、先用python实现一个
代码:
python
class Solution(object):
def compareVersion(self, version1, version2):
""" :type version1: str :type version2: str :rtype: int """
version_1 = [int(i) for i in version1.split('.')]
version_2 = [int (i) for i in version2.split('.')]
len_1 = len(version_1)
len_2 = len(version_2)
if len_1-len_2<=0:
short = version_1
long = version_2
elif len_1-len_2>0:
short = version_2
long = version_1
for i in range(len(short)):
if version_1[i]>version_2[i]:
return 1
elif version_1[i]<version_2[i]:
return -1
else:
pass
flag = True
for i in range(min(len_1,len_2),max(len_1,len_2)):
if long[i] !=0:
flag = False
if len_1>len_2 and flag ==False:
return 1
elif len_1<len_2 and flag == False:
return -1
else:
return 0
结果:48ms
2、将每个点作为分隔符,将之前的字符串转换为数字进行比较
C++
class Solution {
public:
int compareVersion(string version1, string version2) {
int i=0;
int j=0;
int num1 = 0;
int num2 = 0;
int len1 = version1.size();
int len2 = version2.size();
while(i<len1 || j<len2)
{
while(i<len1&&version1[i]!='.')
{
num1 = num1*10+version1[i]-'0';
i++;
}
while(j<len2&&version2[j]!='.')
{
num2 = num2*10+version2[j]-'0';
j++;
}
if(num1>num2) return 1;
else if(num1<num2) return -1;
num1 = 0;
num2 = 0;
i++;
j++;
}
return 0;
}
};
结果:2ms
Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
题意:字符串转为整型
思路:
思路不难,就是容易忽略一些可能的输入情况。
C++
class Solution {
public:
int myAtoi(string str) {
int sign = 1, base = 0, i = 0;
while (str[i] == ' ') { i++; }
if (str[i] == '-' || str[i] == '+') {
sign = 1 - 2 * (str[i++] == '-');
}
while (str[i] >= '0' && str[i] <= '9') {
if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - '0' > 7)) {
if (sign == 1) return INT_MAX;
else return INT_MIN;
}
base = 10 * base + (str[i++] - '0');
}
return base * sign;
}
};
结果:8ms