No.28, Implement strStr()
No.29, Divide Two Integers
第一个题是找子串第一次出现的位置。
这个题最经典的算法当然是线性的KMP,先处理一下子串,拿到子串里面的关系,就不用每次比较都只前进一位了。
这里我就简单做了,从字符串的第一位开始遍历,将该位(包括)之后的字符串和子串比较,如果不是,则前进一位重复比较。这个算法复杂度是O((m-n+1)*n)(m为字符串长度,n为子串长度)
class Solution { public: int strStr(string haystack, string needle) { if(needle.empty()) return 0; for(int i=0;i<haystack.size();i++){ if(needle.size()>haystack.size()-i){ return -1; } bool flag=true; for(int j=0;j<needle.size();j++){ if(haystack[i+j]!=needle[j]){ flag=false; break; } } if(flag){ return i; } } return -1; } };
第二题是两个数做除法,但是不能使用乘除模运算。如果溢出返回MAX_INT。
这里使用位运算。每个正数都可以被写成2的次幂加和,可以通过把除数向左移,一次一次的做减法得到指数的序列,由于是从小往大减的,循环一遍可能没有减完,那么外面还需要一个大循环。取个简单的,15除以2,1111/10->1111-10=1101 res=1 ->1101-100=1001 res=11-> 1001-1000=0001 res=111->跳出循环,最后res=7
这里使用了long long主要是害怕溢出,另外abs里面为了防止溢出也强制转化为了long long,因为abs(MIN_INT)事实上是溢出的。
class Solution { public: int divide(int dividend, int divisor) { if(divisor==0){ return INT_MAX; } long long a=abs((long long)dividend); long long b=abs((long long)divisor); long long result=0; while(a>=b){ long long c=b; for(int i=0;a>=c;i++,c<<=1){ a-=c; result+=1<<i; } } result=((dividend^divisor)>>31)?(-result):result; if(result>INT_MAX) return INT_MAX; return result; } };