初识Leetcode----学习(十八)【Excel表列名称、Excel表列序号、求众数】

Excel表列名称

给定一个正整数,返回它在 Excel 表中相对应的列名称。

例如,

    1 -> A
    2 -> B
    3 -> C
    ...
    26 -> Z
    27 -> AA
    28 -> AB 
    ...

示例 1:

输入: 1
输出: "A"

示例 2:

输入: 28
输出: "AB"

示例 3:

输入: 701
输出: "ZY"

1. 直接判断输入的数字n,用给定的数字n对26求余,余数+‘A’得到低位字符,然后n缩小26倍,依次类推,得到低位到高位的字符,然后再取反即可:

具体分析:

输入n:29

第一轮:ret :'C'     n:1

第二轮:ret :'A'

结果:"AC" -> "CA"

class Solution {
public:
    string convertToTitle(int n) {
        string ret;
        while (n)
        {
            ret += (--n)%26 + 'A';     //此处--n作用是得到正确的字符,比如n为27低位本应得到'A',如不减1则得到'B'
            n /= 26;
        }
        return string(ret.rbegin(), ret.rend());
    }
};

2.将上述思路用递归写法:

class Solution {
public:
    string convertToTitle(int n) {
        return n == 0 ? "" : convertToTitle(n/26) + char(--n%26 + 'A');
    }
};

Excel表列序号

给定一个Excel表格中的列名称,返回其相应的列序号。

例如,

    A -> 1
    B -> 2
    C -> 3
    ...
    Z -> 26
    AA -> 27
    AB -> 28 
    ...

示例 1:

输入: "A"
输出: 1

示例 2:

输入: "AB"
输出: 28

示例 3:

输入: "ZY"
输出: 701

致谢:
特别感谢 @ts 添加此问题并创建所有测试用例。

1.跟上题思路一致,从低位开始计算,然后逐渐计算高位:

class Solution {
public:
    int titleToNumber(string s) {
        int result = 0, n = s.size(), tmp = 1;
        while (n--)
        {
            result += int(s[n] - 'A' + 1) * tmp;
            tmp *= 26;
        }
        return result;
    }
};

求众数

给定一个大小为 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在众数。

示例 1:

输入: [3,2,3]
输出: 3

示例 2:

输入: [2,2,1,1,1,2,2]
输出: 2

1.(我觉得很切题意的方法)直接对数组排序,输出位置为n/2的元素即为众数:

具体分析:

给定数组:2,2,1,1,1,2,2

经sort:1,1,1,2,2,2,2

返回下标3元素,得到2

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(),nums.end());    //对数组进行排序
        return nums[nums.size()/2];       //返回数组中二分之一位置处的元素
    }
};

2.摩尔投票法,参考自Grandyang的博客(还有下面要提的利用位操作Bit Manipulation来求解):

具体分析:

给定数组:2,2,1,1,1,2,2

进行遍历判断:候选人:2    cnt:1

候选人:2  cnt:2

候选人:2  cnt:1

候选人:2   cnt:0    cnt为0更换候选人为1

候选人:1   cnt:1

候选人:1  cnt:0

候选人:2  cnt:1

返回当前候选人:2

//首先此做法的前提是必须有众数存在
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int res = 0, cnt = 0;
        for (int num : nums) {        //遍历数组      
            if (cnt == 0) {res = num; ++cnt;}  //如果投票数为0,则更换候选人,并将当前候选人的票数加1
            else (num == res) ? ++cnt : --cnt; //如果前一候选人与当前候选人相同则投票数++,否则递减投票数
        }
        return res;   //返回众数
    }
};

3.利用位操作Bit Manipulation来求解:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int res = 0, n = nums.size();
        for (int i = 0; i < 32; ++i) {
            int ones = 0, zeros = 0;
            for (int num : nums) {
                if (ones > n / 2 || zeros > n / 2) break;
                if ((num & (1 << i)) != 0) ++ones;
                else ++zeros;
            }
            if (ones > zeros) res |= (1 << i);
        }
        return res;
    }
};

4.利用rand产生随机数,随机选择一个元素看它是否为众数:

具体分析:

输入数组:2,2,1,1,1,2,2

首先产生随机数

第一轮:idx :2   则得到counts = 3不大于一半元素

第二轮:idx :1   则得到counts=4大于一半元素则此元素为众数

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int n = nums.size();
        srand(unsigned(time(NULL)));     //随机数产生
        while (true) {
            int idx = rand() % n;       //产生小于n的下标
            int candidate = nums[idx];   //利用随机数生成的下标访问元素
            int counts = 0; 
            for (int i = 0; i < n; i++)
                if (nums[i] == candidate)   //计算当前元素出现的次数
                    counts++; 
            if (counts > (n-1) / 2) return candidate;  //如果出现次数大于一半的元素个数,则返回该数
        }
    }
};

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/83381293