程序员面试金典84题之每日7题 - 最后一天

第一题:单词最近距离

题目:

有一篇文章内含多个单词,现给定两个单词,请设计一个高效算法,找出文中这两个单词的最短距离(即最少相隔的单词数,也就是两个单词在文章中位置的差的绝对值)。

给定一个string数组article,代表所给文章,同时给定文章的单词数n和待查找的两个单词x和y。请返回两个单词的最短距离。保证两个单词均在文中出现且不相同,同时保证文章单词数小于等于1000。

解析:

class Distance {
public:
	int getDistance(vector<string> article, int n, string x, string y) {
		// write code here
		int distance = 1000;
		int t1 = 2000; int t2 = 1000;
		for (int i = 0; i < n; ++i) {
			if (article[i] == x) t1 = i;
			if (article[i] == y) t2 = i;
			distance = abs(t1 - t2) < distance ? abs(t1 - t2) : distance;
 		}
		return distance;
	}
};

第二题:最长合成字符串

题目:

有一组单词,请编写一个程序,在数组中找出由数组中字符串组成的最长的串A,即A是由其它单词组成的(可重复)最长的单词。

给定一个string数组str,同时给定数组的大小n。请返回最长单词的长度,保证题意所述的最长单词存在。

测试样例:

[“a”,“b”,“c”,“ab”,“bc”,“abc”],6

返回:

3

解析:

class LongestString {
public:
    static bool cmp(string str1,string str2)
    {
        return str1.size()>str2.size();
    }
    int getLongest(vector<string> str, int n) {
        // write code here
        
        sort(str.begin(),str.end(),cmp);
        for(int i=0;i<n;++i)
        {
            string temp = str[i];
            int x;
            for(int j=i+1;j<n;++j)
            {
               while((x=temp.find(str[j]))!=-1)
                {
                    temp.erase(x,str[j].size());
                }
            }
            if(temp.empty()) return str[i].size();
        }
        return -1;
    }
    
};

第三题:子串判断

题目:

现有一个小写英文字母组成的字符串s和一个包含较短小写英文字符串的数组p,请设计一个高效算法,对于p中的每一个较短字符串,判断其是否为s的子串。

给定一个string数组p和它的大小n,同时给定string
s,为母串,请返回一个bool数组,每个元素代表p中的对应字符串是否为s的子串。保证p中的串长度小于等于8,且p中的串的个数小于等于500,同时保证s的长度小于等于1000。

测试样例:

[“a”,“b”,“c”,“d”],4,“abc”

返回:

[true,true,true,false]

解析:

注意:find()函数的用法
str.find(str, beg=0, end=len(string))

  • str – 指定检索的字符串
  • beg – 开始索引,默认为0。
  • end – 结束索引,默认为字符串的长度。

如果包含子字符串返回开始的索引值,否则返回-1。
参考链接

class Substr {
public:
	vector<bool> chkSubStr(vector<string> p, int n, string s) {
		// write code here
		vector<bool> res(n,false);
		for (int i = 0; i < n; ++i) {
			if (s.find(p[i]) != -1) {
				res[i] = true;
			}
		}
		return res;
	}
};

第四题:实时中位数

题目:

现有一些随机生成的数字要将其依次传入,请设计一个高效算法,对于每次传入一个数字后,算出当前所有传入数字的中位数。(若传入了偶数个数字则令中位数为第n/2小的数字,n为已传入数字个数)。

给定一个int数组A,为传入的数字序列,同时给定序列大小n,请返回一个int数组,代表每次传入后的中位数。保证n小于等于1000。

测试样例:

[1,2,3,4,5,6],6

返回:

[1,1,2,2,3,3]

解析:

class Middle {
public:
    vector<int> getMiddle(vector<int> A, int n) {
        // write code here
        vector<int> sorted;
        vector<int> output;
        for (int i = 0; i < n; i++) {
            vector<int>::iterator iter = sorted.begin();
            for ( ; iter != sorted.end(); iter++) {
                if (A[i] <= *iter){
                    break;
                }
            }
            sorted.insert(iter, A[i]);
            output.push_back(sorted[i/2]);
        }
        return output;
    }
};
class Middle {
public:
    vector<int> getMiddle(vector<int> a, int n) {
        // write code here
        vector<int> res(n);
        res[0]=a[0];
        for(int i=1;i<n;i++){
            int temp=a[i];
            int j;
            for(j=i-1;j>=0&&temp<a[j];j--){
                a[j+1]=a[j];      
            }
            a[j+1]=temp;
            res[i]=a[i/2];
        }
        return res;
        
    }
};

第五题:字符串变换

题目:

现有一个字典,同时给定字典中的两个字符串s和t,给定一个变换,每次可以改变字符串中的任意一个字符,请设计一个算法,计算由s变换到t所需的最少步数,同时需要满足在变换过程中的每个串都是字典中的串。

给定一个string数组dic,同时给定数组大小n,串s和串t,请返回由s到t变换所需的最少步数。若无法变换到t则返回-1。保证字符串长度均小于等于10,且字典中字符串数量小于等于500。

测试样例:

[“abc”,“adc”,“bdc”,“aaa”],4,”abc”,“bdc”

返回:

2

解析:

class Change {
    bool difOne(string const& a, string const& b) {
        int cnt = 0;
        for (int i(0), size(a.size()); i < size; ++i) {
            if (a[i] != b[i]) ++cnt;
        }
        return cnt == 1;
    }
    bool checkIn(vector<string> const& dic, int n, string const& s, string const& t) {
        bool sIn = false, tIn = false;
        for (int i = 0; i < n; ++i) {
            if (dic[i] == s) sIn = true;
            if (dic[i] == t) tIn = true;
        }
        return sIn && tIn;
    }
public:
    int countChanges(vector<string> const& dic, int n, string const& s, string const& t) {
        if (s.size() != t.size() || !checkIn(dic, n, s, t)) return -1;
        if (s == t) return 0;
        list<string> unused;
        copy_if(dic.begin(), dic.end(), back_inserter(unused),
            [&s](string const& str) { return str != s && str.size() == s.size(); });
        queue<string> que;
        que.push(s);
        for (int level = 1; que.size(); ++level) {
            for (int i(que.size()); i > 0; --i) {
                string const& cur = que.front();
                for (auto it = unused.begin(); it != unused.end(); ) {
                    if (difOne(cur, *it)) {
                        if (*it == t) return level;
                        que.push(*it);
                        it = unused.erase(it);
                    } else {
                        ++it;
                    }
                }
                que.pop();
            }
        }
        return -1;
    }
};

第六题:最大子方阵

题目:

有一个方阵,其中每个单元(像素)非黑即白(非0即1),请设计一个高效算法,找到四条边颜色相同的最大子方阵。

给定一个01方阵mat,同时给定方阵的边长n,请返回最大子方阵的边长。保证方阵边长小于等于100。

测试样例:

[[1,1,1],[1,0,1],[1,1,1]],3

返回:

3

解析:

遍历所有,对每一个可能的长度进行验证

class SubMatrix {
public:
	int maxSubMatrix(vector<vector<int> > mat, int n) {
		// write code here
		int maxLength = n;
		while (maxLength) {
			for (int i = 0; i <= n - maxLength; ++i) {
				for (int j = 0; j <= n - maxLength; ++j) {
					int pixel = mat[i][j];
					bool flag = true;
					for (int k = 0; k < maxLength; ++k) {
						int top = mat[i][j + k];	// 上边的线
						int bottom = mat[i + maxLength - 1][j + k];  // 下边的线
						int left = mat[i + k][j];	// 左边的线
						int right = mat[i + k][j + maxLength - 1];	 // 右边的线
						if (top != pixel || bottom != pixel || left != pixel || right != pixel) {
							flag = false;
							break;
						}
					}
					if (flag) return maxLength;
				}
			}
			maxLength--;
		}
		return 0;
	}
};

第七题:最大和子矩阵

题目:

有一个正整数和负整数组成的NxN矩阵,请编写代码找出元素总和最大的子矩阵。请尝试使用一个高效算法。

给定一个int矩阵mat和矩阵的阶数n,请返回元素总和最大的子矩阵的元素之和。保证元素绝对值小于等于100000,且矩阵阶数小于等于200。

测试样例:

[[1,2,-3],[3,4,-5],[-5,-6,-7]],3

返回:

10

解析:

对每一行,与下面行累加,得到一个一维数组,用一维数组求连续子数组的最大和的方式求出最大和

class SubMatrix {
public:
    int sumOfSubMatrix(vector<vector<int> > mat, int n) {
        // write code here
        int maxsum=0,submax=0;
        for(int time=0;time<n;time++)
        {
            vector<int> v(n,0);
            for(int i=time;i<n;i++)
            {
                submax=0;
                for(int j=0;j<n;j++)
                {
                    v[j]+=mat[i][j];
                    submax=max(v[j],v[j]+submax);
                    maxsum=max(maxsum,submax);
                }
            }
        }
        return maxsum;
    }
};

第八题:最大字母矩阵

题目:

有一个单词清单,请设计一个高效算法,计算由清单中单词组成的最大子矩阵,要求矩阵中的行和列都是清单中的单词。

给定一个string数组dic,代表单词清单,同时给定清单的大小n,请返回最大子矩阵的面积。保证单词清单的大小小于等于50,且某一长度的串的数量小于等于12。

测试样例:

[“aaa”,“aaa”,“aaa”,“bb”,“bb”]

返回:

9

解析:

class AlphaMatrix {
public:
    int findAlphaMatrix(vector<string> dic, int n) {
        // write code here
        set<string> temp;
        int res = 0;
        for(int i = 0; i < n; i++){
            string word = dic[i];
            if(temp.find(word)!= temp.end())continue;
            temp.insert(word);
            int count = 1;
            for(int j = i + 1; j < n; j++){
                string word2 = dic[j];
                if(word.compare(word2))break;
                ++count;
            }
            i += count - 1;
            if(count * word.size() > res)res = count * word.size();
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值