面试笔试杂项积累-leetcode 11-15

11.9-Palindrome Number-Difficulty: Easy

Determine whether an integer is a palindrome. Do this without extra space.

click to show spoilers.

Some hints:

Could negative integers be palindromes? (ie, -1)

If you are thinking of converting the integer to string, note the restriction of using extra space.

You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case?

There is a more generic way of solving this problem.

方法一

思路

题目要求判断int是否为回文,并要求不许使用额外的空间,博主打算裁一下int的方法,依旧使用传入的int来判断,int值为负时不是回文,博主在此踩了坑


然后博主没有考虑像100021这样的情况,思索片刻后,决定记录int长度来比对,如果000被消去的话当前长度肯定比记录长度小,此时判断后面的数字是否为0即可

循环方面,循环次数为数长度/2,int长度的求法在c#中有两种,

1.Math.Log(x);

2.x.ToString().Length

之后就没什么问题了

public class Solution {
    public bool IsPalindrome(int x)
    {
        if (x < 0)
            return false;
        int temp = x.ToString().Length;
        for (int i = 1; i < temp; )
        {
            if (temp > x.ToString().Length)
            {
                if ((x % (Math.Pow(10, i)) == 0))
                {
                    x = (int)(x * 0.1);
                    temp -= 2;
                    continue;
                }
                else
                    return false;
    �       }
            if (((int)(x / Math.Pow(10, x.ToString().Length - i)))  == (x % (Math.Pow(10, i))))
            {
                x -= (int)(((int)(x / Math.Pow(10, x.ToString().Length - i))) * Math.Pow(10, x.ToString().Length - i));
                x = (int)(x*0.1);
                temp-=2;
                continue;
            
            }
            else return false;
        }
        return true;
    }
}

改法二

思路

将int中转string后转化为char数组再操作,挨个[i]循环比对,是个机智简单的方法

参考:

http://blog.csdn.net/cxming007/article/details/24022361

    public bool IsPalindrome2(int x)
    {
        String str = x.ToString();
        char[] strChar = str.ToCharArray();
        int intL = strChar.Length;
        int length = strChar.Length >> 1;
        int i = 0;
        while (i < length)
        {
            if (strChar[i] != strChar[intL - i - 1])
            {
                return false;
            }
            i++;
        }
        return true;
    }  

12.12-Integer to Roman-Difficulty: Medium

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.

方法一

思路

题目要求输入一个int返回string类型的的罗马数字

罗马数字对照表:用来核验

http://wenku.baidu.com/link?url=_AplOykp9g1VOea8nZZt2UnY4kBClT1_D0-vMnxjd0xSg8XTXJJ9rOF3RoskyZRwrmYSvpS3A9hGmq2iNXyDxKahDrGhaYsFZ1fV1as7p13

1~9: {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};

10~90: {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};

100~900: {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};

1000~3000: {"M", "MM", "MMM"}.

博主是使用了一个矩阵,严格来讲是c#的锯齿数组,把上面的罗马数字放进去,再一一对应

如果矩阵格式是像博主这样的,要注意100,10这样末尾是0的数,会在-1时发生超界,可以像博主一样加上判断,还可以是矩阵的每行第0个数为空像下面这样

        roman[0] = new string[10] { "","I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" };
        roman[1] = new string[10] { "","X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" };
        roman[2] = new string[10] { "","C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" };
        roman[3] = new string[10] { "","M", "MM", "MMM" };

 

public class Solution {
    public string IntToRoman(int num) {
      if (num == 0)
            return "";


        string[][] roman = new string[4][];
        roman[0] = new string[9] { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" };
        roman[1] = new string[9] { "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" };
        roman[2] = new string[9] { "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" };
        roman[3] = new string[3] { "M", "MM", "MMM" };
        string str = num.ToString();
        string final = "";

        for (int i = 0; i < str.Length; i++)
        {
            if (int.Parse(str[i].ToString())!=0)
            final += roman[str.Length-1-i][int.Parse(str[i].ToString()) - 1];
        }
        return final;
    }
}

方法二

思路

已知罗马数字就是那么几个字母组成的,而且字母是可以叠加的,所以只把那些字母存在数组中,再累加即可
参考

http://blog.csdn.net/havenoidea/article/details/11848921

class Solution {  
public:  
    string intToRoman(int num) {  
        string str;    
        string symbol[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};    
        int value[]=    {1000,900,500,400, 100, 90,  50, 40,  10, 9,   5,  4,   1};   
        for(int i=0;num!=0;++i)  
        {  
            while(num>=value[i])  
            {  
                num-=value[i];  
                str+=symbol[i];  
            }  
        }  
        return str;  
    }  

方法一空间复杂度高高于方法二,而时间复杂度低于方法二

13.13-Roman to Integer-Difficulty: Easy

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.

方法一

思路

不太理解为什么1这道题是easy难度,上一道题是medium。受上一道题的影响还是采用存入数组再一一映射的方法,博主把单个字母和双个字母分开了,麻烦了一些,没有掌握罗马字的奥秘啊。。。,机智的方法请看法二

public class Solution {
    public int RomanToInt(string s) {
            string[] symbol1 = new string[7] { "M", "D", "C", "L", "X", "V", "I" };
        string[] symbol2 = new string[6] { "CM", "CD", "XC", "XL", "IX", "IV" };
        int[] value1 = new int[7] { 1000, 500, 100, 50, 10, 5, 1 };
        int[] value2 = new int[6] { 900, 400, 90, 40, 9, 4 };
        int final = 0;
        bool isTwo = false;
        for (int i = 0; i < s.Length; i++)
        {
            if (i < s.Length - 1)
                for (int j = 0; j < 6; j++)
                {
                    if (s[i].ToString() + s[i + 1].ToString() == symbol2[j])
                    {
                        final += value2[j];
                       ++i;
                       isTwo = true;
                        break;
                    }
                }
            if (isTwo)
            {
                isTwo = false;
                continue;
            }
            for (int j = 0; j < 7; j++)
            {
                if (s[i].ToString() == symbol1[j])
                    final += value1[j];
            }
        }
        return final;
    }
}

方法二

思路

这个方法就很好的体现及运用了罗马字的原则,如果是双字,前面字母映射的数值是小于后面的,双字的值为后字减前字*2

参考:

http://blog.csdn.net/ljiabin/article/details/39968583

    class Solution {  
    public:  
        int romanToInt(string s) {  
            int ret = toNumber(s[0]);  
            for (int i = 1; i < s.length(); i++) {  
                if (toNumber(s[i - 1]) < toNumber(s[i])) {  
                    ret += toNumber(s[i]) - 2 * toNumber(s[i - 1]);  
                } else {  
                    ret += toNumber(s[i]);  
                }  
            }  
            return ret;  
        }  
          
        int toNumber(char ch) {  
            switch (ch) {  
                case 'I': return 1;  
                case 'V': return 5;  
                case 'X': return 10;  
                case 'L': return 50;  
                case 'C': return 100;  
                case 'D': return 500;  
                case 'M': return 1000;  
            }  
            return 0;  
        }  
    };  

14.14-Longest Common Prefix-Difficulty: Easy


Write a function to find the longest common prefix string amongst an array of strings.

思路

题目要求传入一个string数组,比较这些数组最长的相同前缀,博主采用整体比较的方法,遍历每个string,判断是否相等,有一个不相等立刻return,

此处要注意string数组是否全部为空,博主弄了一个临时int计算空值数目,一次循环之后再与length比对,相同即全部为空返回""。

public class Solution {
    public string LongestCommonPrefix(string[] strs) {
        if (strs.Length ==1 )
            return strs[0];
        string final = "";
        int repeat = 0;
        for (int j = 0; ; j++)
        {
            for (int i = 0; i < strs.Length - 1; i++)
            {
                if (strs[i] == null)
                {
                    ++repeat;
                    continue;
                }
                if (strs[i + 1].Length <= final.Length||j>=strs[i].Length)
                    return final;
                if (strs[i][j] == strs[i + 1][j])
                {
                    continue;
                }
                else
                    return final;
            }
            if (repeat >= strs.Length - 1)
                return "";// null;
                final += strs[0][j];
        }
    }
}

15.15-3Sum-Difficulty: Medium

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, abc)
  • The solution set must not contain duplicate triplets.
    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)

思路

题目要求给入一个数组,在求出所有相加等于0的三个数的集合

注意

1.集合中不能有重复的三位数

2.三位数必须按从小到大的顺序排列

看过题之后,博主天真的认为三个循环遍历就好了,结果果不其然就超时了,随后就仔细的把不可能的情况判断排除了一下,结果还是超时,说明最坏的情况下时间复杂度还是O(n^3),遂求救网络,查到一个O(n^2)的方法,就是在第二个循环中操作判断第二个和第三个数,顺便把不可能的情况判断排除。

首先为了使第二个注意成立,也就是-三位数必须按从小到大的顺序排列,我们先把array进行sort处理,就无后顾之忧了。

参考:

http://www.programcreek.com/2012/12/leetcode-3sum/
public class Solution {
    public IList<IList<int>> ThreeSum(int[] nums)//测试中
    {
      IList<IList<int>> result = new List<IList<int>>();

        if (nums.Length < 3)
            return result;

        // sort array
        Array.Sort(nums);
        List<int> temp;
        for (int i = 0; i < nums.Length - 2; i++)
        {
            // //avoid duplicate solutions
            if (i == 0 || nums[i] > nums[i - 1])
            {

                int negate = -nums[i];

                int start = i + 1;
                int end = nums.Length - 1;

                while (start < end)
                {
                    //case 1
                    if (nums[start] + nums[end] == negate)
                    {
                        temp = new List<int>();
                        temp.Add(nums[i]);
                        temp.Add(nums[start]);
                        temp.Add(nums[end]);

                        result.Add(temp);
                        start++;
                        end--;
                        //avoid duplicate solutions
                        while (start < end && nums[end] == nums[end + 1])
                            end--;

                        while (start < end && nums[start] == nums[start - 1])
                            start++;
                        //case 2
                    }
                    else if (nums[start] + nums[end] < negate)
                    {
                        start++;
                        //case 3
                    }
                    else
                    {
                        end--;
                    }
                }

            }
        }

        return result;
    }


}
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值