算法第三周解题报告

题目名称:Valid Number

题目描述:

Validate if a given string is numeric.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.


解题思路: 这题是本人至今在leetcode遇到过的最复杂的题目,难点有二:

1.题目的输入范围不明确,有效数字的形式只能通过先验知识以及测试样例得出。

2.由于有效数字的范围比较广,表现形式比较复杂,因此在画状态机的时候状态机十分繁琐,以至于好几次状态机都画不下去了。

最后我的做法是:将数字先简单分类为十进制数和十六进制数两类讨论,再用两个标志位记录是否有小数点、是否有指数符号e,从而更好地分类讨论,解决了问题。

代码如下:

using namespace std;
class Solution {

public:

	bool isNumber(string s) {
		if (s.length() == 0) return false;
		int begin = 0;
		int end = s.length() - 1;
		while (s[begin] == ' ') ++begin;
		while (s[end] == ' ') --end;
		if (begin > end) return false;
		if (s[begin] == '+' || s[begin] == '-'){
			++begin;
		}
		if (s[end] == 'l' || s[end] == 'f') {
			--end;
			if (end < 0 || s[end] < '0' || s[end] > '9')return false;
		}
		return  isNumber(s, begin, end);
	}
	bool isInteger(const string& s, int begin, int end, int& index){
		if (begin > end) {
			index = begin;
			return false;
		}
		for (int i = begin; i <= end; ++i){
			if (s[i] > '9' || s[i] <'0'){
				index = i;
				return false;
			}
		}
		return true;
	}
	bool isNumber(const string& s, int begin, int end){
		//ox NUmber
		if (begin == end && s[begin] == '.') return false;
		if (begin == end && s[begin] == 'e') return false;
		if (end - begin >= 1 && s[begin] == 0 && s[begin + 1] == 'x')
			return isInteger(s, begin + 2, end, end);
		int index = 0;
		bool IsInt = isInteger(s, begin, end, index);
		if (IsInt == true) return true;
		if (IsInt == false && s[index] == '.'){
			begin = index + 1;
			if (begin > end) return true;
			IsInt = isInteger(s, begin, end, index);
			if (IsInt == true) return true;
			else if (index >= begin){
				if (s[index] == 'e') return isInteger(s, index + 1,
					end, index);
				else return false;
			}
			else{
				return false;
			}
		}
		else if (IsInt == false && s[index] == 'e' && index - begin != 0){
			return isInteger(s, index + 1, end, index);
		}
		else return false;
	}

};
结果如下:



题目名称: Longest Palindromic Substring

题目描述:

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example:

Input: "babad"

Output: "bab"

Note: "aba" is also a valid answer.

题目分析:这一题看似简单,但是对算法时间上的要求较高。第一次实现时我用了最简单的三重循环遍历,最后超时了。最后参考了其他CSDN的实现使用了动规算法以o(n2)的时间复杂度AC了。

动规的思路如下:

1.写出动态转移方程。

P[ i, j ] ← true iff the substring Si … Sj is a palindrome, otherwise false.

P[ i, j ] ← ( P[ i+1, j-1 ] and Si = Sj ) ,如果一个子串是回文串,并且如果从它的左右两侧分别向外扩展的一位也相等,那么这个子串就可以从左右两侧分别向外扩展一位。

其中的base case是

P[ i, i ] ← true
P[ i, i+1 ] ← ( Si = Si+1 )

代码如下:

#include<algorithm>
using namespace std;
class Solution {


public:
	string longestPalindrome(string s) {
		if (s.length() == 1) return s;
		if (s.length() == 0) return "";
		bool **table = new bool *[s.length()];
		for (int i = 0; i < s.length(); ++i){
			table[i] = new bool[s.length()];
		}
		// table estable
		for (int i = 0; i < s.length(); ++i){
			for (int j = 0; j < s.length(); ++j){
				table[i][j] = (i >= j ? true : false);
			}
		}
		for (int i = s.length() - 2; i >= 0; --i){
			for (int j = s.length() - 1; j > i; --j){
				if (s[i] == s[j]){
					table[i][j] = table[i + 1][j - 1];
				}
				else {
					table[i][j] = false;
				}
			}
		}
		//test code
		/*for (int i = 0; i < s.length(); ++i){
			for (int j = 0; j < s.length(); ++j){
				cout << table[i][j] << " ";
			}
			cout << endl;
		}*/
		int begin = -1;
		int end = -1;
		int maxL = 0;
		for (int i = 0; i < s.length(); ++i){
			for (int j = i; j < s.length(); ++j){
				if (table[i][j] == true){
					if (j - i + 1 > maxL){
						begin = i;
						end = j;
						maxL = j - i + 1;
					}
				}
			}
		}
		return s.substr(begin, maxL);
	}
};
结果如下:


题目名称: Implement strStr()

题目描述:

Implement strStr().

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Subscribe to see which companies asked this question.

解题思路:KMP算法。

代码如下:

#include<iostream>
#include<string>

using namespace std;

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle.length() > haystack.length()) return -1;
        if(needle.length() == 0) return 0;
        int *next = getNext(needle);
        int j = 0;
        int curIndex = -1;
        int length1 = needle.length();
        int length = haystack.length();
        for(int i = 0; i < length; ++i){
            while( j > 0 && needle[j] != haystack[i]){
                j = next[j];
            }
            if(needle[j] == haystack[i]) 
                ++j;
            if(j == length1){
                return i - j + 1;
            }
        }
        return -1;
    }
    int *getNext(string& needle){
        int length = needle.length();
        int *next = new int[needle.length() + 1];
        next[0] = next[1] = 0;
             int length1 = needle.length();
        for(int i = 1; i < length1; ++i){
            int j = next[i];
            while(j > 0 && needle[i] != needle[j]){
                j = next[j];
            }
            if(needle[i] == needle[j]){
                j = j + 1;
            }
            next[i + 1] = j;
        }
        return next;
    }
};

结果如下:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值