程序员面试金典84题之每日7题 - 第二天

第一题:翻转子串

题目:

假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串。请将这个算法编写成一个函数,给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成,要求只能调用一次检查子串的函数。

给定两个字符串s1,s2,请返回bool值代表s2是否由s1旋转而成。字符串中字符为英文字母和空格,区分大小写,字符串长度小于等于1000。

测试样例:

“Hello world”,"worldhello "
返回:false
“waterbottle”,“erbottlewat”
返回:true

解析:

注意:string 中find()函数的用法

class ReverseEqual {
public:
	bool checkReverseEqual(string s1, string s2) {
		// write code here
		if (s1.size() != s2.size()) return false;
		string ss = s1 + s1;
		if (ss.find(s2) == string::npos) return false;
		return true;
	}
};

第二题:链表中倒数第k个结点

题目:

输入一个链表,输出该链表中倒数第k个结点。

解析:

注意:链表比k小的情况

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};
class Solution {
public:
	ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
		auto fast = pListHead;
		for (int i = 0; i < k; ++i) {
			if (fast == nullptr) return nullptr;
			fast = fast->next;
		}
		auto low = pListHead;
		while (fast != nullptr) {
			low = low->next;
			fast = fast->next;
		}
		return low;
	}
};

第三题:访问单个节点的删除

题目:

实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点。

给定待删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true

解析:

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
class Remove {
public:
	bool removeNode(ListNode* pNode) {
		// write code here
		if (pNode->next == nullptr) return false;
		else
		{
			pNode = pNode->next;
			return true;
		}
	}
};

第四题:链表分割

题目:

编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前

给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。

解析:

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
class Partition {
public:
	ListNode* partition(ListNode* pHead, int x) {
		// write code here
		if (pHead == nullptr) return nullptr;
		ListNode* head1 = new ListNode(0);
		ListNode* head2 = new ListNode(0);
		ListNode* cur1 = head1;
		ListNode* cur2 = head2;
		while (pHead != nullptr)
		{
			if (pHead->val < x) {
				head1->next = pHead;
				head1 = head1->next;
			}
			else
			{
				head2->next = pHead;
				head2 = head2->next;
			}
			pHead = pHead->next;
		}
		head2->next = nullptr;
		head1->next = cur2->next;
		return cur1->next;
	}
};

第五题:链式A+B

题目:

有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。编写函数对这两个整数求和,并用链表形式返回结果。

给定两个链表ListNode* A,ListNode* B,请返回A+B的结果(ListNode*)。

测试样例:

{1,2,3},{3,2,1}
返回:{4,4,4}

解析:

注意:1、 a或b其中一个为空,则没有a = a->next (或b = b->next);
2、记得进位

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
class Plus {
public:
	ListNode* plusAB(ListNode* a, ListNode* b) {
		// write code here
		if (a == nullptr && b == nullptr) return nullptr;
		ListNode* phead = new ListNode(0);
		ListNode* res = phead;
		int flag = 0;
		while (a != nullptr || b != nullptr) {
			int numa = a == nullptr ? 0 : a->val;
			if(a != nullptr) a = a->next;
			int numb = b == nullptr ? 0 : b->val;
			if (b != nullptr) b = b->next;
			int number = numa + numb +flag;
			phead->next = new ListNode(number % 10);
			flag = number / 10;
			phead = phead->next;
		}
		if (flag == 1) phead->next = new ListNode(1);
		return res->next;
	}
};

第六题:回文链表

题目:

请编写一个函数,检查链表是否为回文。

给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。

测试样例:

{1,2,3,2,1}
返回:true
{1,2,3,2,3}
返回:false

解析:

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
class Palindrome {
public:
	bool isPalindrome(ListNode* pHead) {
		// write code here
		ListNode* cur = pHead;
		vector<int> res;
		while (cur) {
			res.push_back(cur->val);
			cur = cur->next;
		}
		int t = res.size() - 1;
		for (int i = 0; i < res.size(); ++i) {
			if (res[i] != res[t - i]) return false;
			if (i >= t - i) return true;
		}
	}
};

第七题:集合栈

题目:

请实现一种数据结构SetOfStacks,由多个栈组成,其中每个栈的大小为size,当前一个栈填满时,新建一个栈。该数据结构应支持与普通栈相同的push和pop操作。

给定一个操作序列int[][2] ope(C++为vector<vector<int>>),每个操作的第一个数代表操作类型,若为1,则为push操作,后一个数为应push的数字;若为2,则为pop操作,后一个数无意义。请返回一个int[],为完成所有操作后的SetOfStacks,顺序应为从下到上,默认初始的SetOfStacks为空。保证数据合法。

解析:

class SetOfStacks {
public:
	vector<vector<int> > setOfStacks(vector<vector<int> > ope, int size) {
		// write code here
		stack<int> st1;
		int count = 0;
		for (int i = 0; i < ope.size(); ++i) {
			ope[i][0] == 1 ? st1.push(ope[i][1]) : st1.pop();
		}
		stack<int> st2;
		while (!st1.empty()) {
			st2.push(st1.top());
			st1.pop();
		}
		vector<vector<int>> res;
		while (!st2.empty()) {
			vector<int> tmp;
			for (int i = 0; i < size; ++i) {
				tmp.push_back(st2.top());
				st2.pop();
				if (st2.empty()) break;
			}
			res.push_back(tmp);
		}
		return res;
	}
};

你可能感兴趣的:(程序员面试金典84题系列)