leetcode题解日练--2016.7.2

编程日记,尽量保证每天至少3道leetcode题,仅此记录学习的一些题目答案与思路,尽量用多种思路来分析解决问题,不足之处还望指出。标红题为之后还需要再看的题目。

今日题目:1、旋转数组;2、比较版本号;3、字符串转整型。

189. Rotate Array My Submissions QuestionEditorial Solution

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

165. Compare Version Numbers | Difficulty: Easy

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

8. String to Integer (atoi)|Difficulty: Easy

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值