[Leetcode] 2-3-4-5-8-13

13. 罗马数字转整数

在这里插入图片描述
在这里插入图片描述

方法一 比较当前字符,并获取下一位字符

class Solution {
public:

    int GetRomanValue(const char ch)
    {
        if(ch == 'I') return 1;
        else if(ch == 'V') return 5;
        else if(ch == 'X') return 10;
        else if(ch == 'L') return 50;
        else if(ch == 'C') return 100;
        else if(ch == 'D') return 500;
        else if(ch == 'M') return 1000;
        else return 0;
    }

    int GetValue(const string s,int iPos)
    {
        int iSize = s.size();
        int iPos2 = iPos+1;
        int iValue = 0;
        if(iPos < iSize) iValue = GetRomanValue(s[iPos]);
        if(iPos2 < iSize)
        {
            if(s[iPos] == 'I' && (s[iPos2] == 'V' || s[iPos2] == 'X')) iValue *= -1;
            else if(s[iPos] == 'X' && (s[iPos2] == 'L' || s[iPos2] == 'C')) iValue *= -1;
            else if(s[iPos] == 'C' && (s[iPos2] == 'D' || s[iPos2] == 'M')) iValue *= -1;
        }
        return iValue;
    }

    int romanToInt(string s) {
        int iValue = 0;
        for(int i=0; i < s.size(); ++i)
        {
            iValue += GetValue(s,i);
        }
        return iValue;
    }
};

方法一改进 GetValue方法中,判断下一位字符时,直接取值,并修改iPos的值

 int GetValue(const string s,int& iPos)
    {
        int iSize = s.size();
        int iPos2 = iPos+1;
        int iValue = 0;
        char ch1 =s[iPos];
        if(iPos < iSize) iValue = GetRomanValue(ch1);
        if(iPos2 < iSize)
        {
            char ch2 = s[++iPos];
            if((ch1 == 'I' && (ch2 == 'V' || ch2 == 'X')) ||
            (ch1 == 'X' && (ch2 == 'L' || ch2 == 'C')) ||
            (ch1 == 'C' && (ch2 == 'D' || ch2 == 'M'))) 
            {iValue = -1*iValue + GetRomanValue(ch2);}
            else --iPos;
        }
        return iValue;
    }

修改完之后运行时间更快了,因为空间复杂度为O(n)了。
在这里插入图片描述

方法二 可使用map,直接将可搭配的组合写入map中,然后根据前后字符查找即可,但须开辟额外空间。

2. 两数相加

在这里插入图片描述
在这里插入图片描述

思路 每次相加需要记录进位carry

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        if(l1->val==0 && !l1->next) return l2;
        if(l2->val==0 && !l2->next) return l1;
        ListNode *result= new ListNode(0);
        ListNode *current = result;
        int carry = 0;
        while(l1 || l2)
        {
            int x = l1?l1->val:0;
            int y = l2?l2->val: 0;
            int sum = x+y+carry;
            carry = sum/10;
            current->next = new ListNode(sum%10);
            current = current->next;
            if (l1) l1 = l1->next;
            if(l2) l2= l2->next;
        }
        if(carry > 0)
        {
            current->next = new ListNode(carry);
        }
        return result->next;
    }
};

3. 无重复字符的最长子串

在这里插入图片描述

方法一 创建一个vector,记录每次不重复的字符串

class Solution {
public:
	bool hasRepeatChar(vector<char>& vec, const char	ch,int& iPos)
	{
		std::vector<char>::iterator iter;
		for (iter = vec.begin(); iter!=vec.end();++iter)
		{
			if (*iter == ch)
			{
				iPos = iter - vec.begin();
				return true;
			}
		}
		return false;
	}

	int lengthOfLongestSubstring(string s) {
		int iSize = s.size();
		if (iSize == 0 || iSize == 1)
			return iSize;
		vector<char> vec;
		int iLeft = 0;
		int iRight = 1;
		int iMax = 0;
		int iPos = -1;
		vec.push_back(s[0]);
		while (iRight <= iSize)
		{
			if (hasRepeatChar(vec, s[iRight], iPos))
			{
				iLeft = iPos;
				if(vec.size()  > iMax) iMax = vec.size();
				vec.erase(vec.begin(), vec.begin() + iPos+1);
			}
			vec.push_back(s[iRight]);
			++iRight;
		}
		if (vec.size()-1 > iMax) iMax = vec.size()-1;
		return iMax;
	}
};

方法二 每次通过iLeft和iRight记录不重复字符串左右索引

class Solution {
public:
bool hasRepeatChar(const string& s, int& iLeft, int& iRight,int& iPos)
{
	if (iRight < iLeft) return false;
	char ch = s[iRight];
	for (int i = iLeft; i < iRight; ++i)
	{
		if (s[i] == ch)
		{
			iPos = iRight - iLeft;
			iLeft =i+1;
			return true;
		}
	}
	return false;
}

int lengthOfLongestSubstring(string s) {
	int iSize = s.size();
	if (iSize == 0 || iSize == 1)
		return iSize;
	int iLeft = 0;
	int iRight = 1;
	int iMax = 1;
	int iPos = -1;
	while (iRight < iSize)
	{
		if (hasRepeatChar(s, iLeft, iRight,iPos))
		{
			if (iPos  > iMax) iMax = iPos;
		}
		++iRight;
	}
	if (iRight - iLeft  > iMax) iMax = iRight - iLeft;
	return iMax;
}
};

4. 寻找两个正序数组的中位数

在这里插入图片描述

方法 先判断总个数为奇数还是偶数,然后依次比较两个数组中的值,奇数取iSum / 2的值,偶数取iSum / 2与iSum / 2+1的平均数

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
	int iSize1 = nums1.size();
	int iSize2 = nums2.size();
	int iSum = iSize1 + iSize2;
	if (iSize1 == 0 && iSize2 == 0)
	{
		return 0.0;
	}
	else if (iSize1 == 0 && iSize2 != 0)
	{
		if ((iSize2 & 1) != 0) return nums2[iSize2 / 2];
		else if ((iSize2 & 1) == 0) return (nums2[iSize2 / 2] + nums2[iSize2 / 2 - 1]) / 2.0;
	}
	else if (iSize1 != 0 && iSize2 == 0)
	{
		if ((iSize1 & 1) != 0) return nums1[iSize1 / 2];
		else if ((iSize1 & 1)== 0) return (nums1[iSize1 / 2] + nums1[iSize1 / 2 - 1]) / 2.0;
	}
	else
	{
		int i1 = 0;
		int i2 = 0;
		int num = 0;
		int iCount = 0;
		if ((iSum & 1) != 0)  //总个数为奇数
		{
			while (iCount != iSum / 2+1)
			{
				if (i1 < iSize1 && i2 < iSize2 && nums1[i1] > nums2[i2])
				{
					num = nums2[i2];
					++i2;
				}
				else 	if (i1 < iSize1 && i2 < iSize2 && nums1[i1] <= nums2[i2])
				{
					num = nums1[i1];
					++i1;
				}
				else if (i1 >= iSize1 && i2 < iSize2)
				{
					num = nums2[i2];
					++i2;
				}
				else if (i2 >= iSize2 && i1 < iSize1)
				{
					num = nums1[i1];
					++i1;
				}
				++iCount;
			}
			return num;
		}
		else if ((iSum & 1) == 0)  //总个数为偶数
		{
			while (iCount != iSum / 2+1)
			{
				++iCount;
				if (i1 < iSize1 && i2 < iSize2 && nums1[i1] > nums2[i2])
				{
					if (iCount == iSum / 2  || iCount == iSum / 2+1) num += nums2[i2];
					++i2;
				}
				else if (i1 < iSize1 && i2 < iSize2 && nums1[i1] <= nums2[i2])
				{
					if (iCount == iSum / 2  || iCount == iSum / 2 + 1) num += nums1[i1];
					++i1;
				}
				else if (i1 >= iSize1 && i2 < iSize2)
				{
					if (iCount == iSum / 2 || iCount == iSum / 2 + 1) num += nums2[i2];
					++i2;
				}
				else if (i2 >= iSize2 && i1 < iSize1)
				{
					if (iCount == iSum / 2 || iCount == iSum / 2 + 1) num += nums1[i1];
					++i1;
				}
			}
			return num/2.0;
		}
	}
	return 0.0;
}
    };

5. 最长回文子串

在这里插入图片描述

参考官方 中心扩展算法:我们枚举所有的「回文中心」并尝试「扩展」,直到无法扩展为止,此时的回文串长度即为此「回文中心」下的最长回文串长度。我们对所有的长度求出最大值,即可得到最终的答案。

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    pair<int,int> FindMaxLength(const string& s,int iLeft,int iRight)
    {
        int iSize = s.size();
        while(iLeft >=0 && iRight <= iSize && s[iLeft] == s[iRight])
        {
            --iLeft;
            ++iRight;
        }
        return{++iLeft,--iRight};
    }

    string longestPalindrome(string s) {
            int iSize = s.size();
            int iStart = 0;
            int iEnd = 0;
            if(iSize == 0) return "";
            else if(iSize == 1) return s;
            else 
            {
                for(int i=0; i < iSize; ++i)
                {
                    auto[iLeft1,iRight1] = FindMaxLength(s,i,i);
                    if((iRight1 - iLeft1) > (iEnd -iStart)) 
                    {
                        iStart = iLeft1;
                        iEnd = iRight1;
                    }
                    auto[iLeft2,iRight2] = FindMaxLength(s,i,i+1);
                    if((iRight2 - iLeft2) > (iEnd -iStart)) 
                    {
                        iStart = iLeft2;
                        iEnd = iRight2;
                    }
                }
            }
            return s.substr(iStart,iEnd-iStart+1);
    }
};

8. 字符串转换整数 (atoi)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方法 设置一个long long lRes存储结果, 并且当lRes超过了INT最大最小范围时,会溢出,所以每次需要判断,防止结果溢出:lRes = bPositive ? min(lRes, (long long)INT_MAX) : min(lRes, -(long long)INT_MIN)

class Solution {
public:
int myAtoi(string s) {
	int iSize = s.size();
	if (iSize == 0) return 0;
	string sRes;
	char c;
	bool bPositive = true;
	bool bStart = false;
	long long lRes = 0;
	int i = 0;
	while (!bStart)
	{
		if (i >= iSize) break;
		c = s[i++];
		if (c == ' ') continue;
		else if (c == '-' || c == '+')
		{
			bPositive = c == '-' ? false : true;
			bStart = true;
		}
		else if (c >= '1' && c <= '9')
		{
			sRes += c;
			lRes = c - '0';
			bStart = true;
		}
		else if (c == '0')
		{
			bStart = true;
		}
		else break;
	}
	if (!bStart) return 0;
	while (bStart)
	{
		if (i >= iSize) break;
		c = s[i++];
		if (sRes == "" && c == '0') continue;
		if (c >= '0' && c <= '9')
		{
			sRes += c;
			lRes = lRes * 10 + c - '0';
			lRes = bPositive ? min(lRes, (long long)INT_MAX) : min(lRes, -(long long)INT_MIN); //防止溢出
		}
		else break;
	}
	if (sRes == "")
	{
		return 0;
	}
	if (!bPositive)
	{
		lRes *= -1;
	}
	return lRes;
}

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值