算法题C++(二)

本博客目录

  • 转圈打印矩阵
  • 旋转正方形矩阵
  • “之”字形打印矩阵
  • 反转单向链表
  • 打印有序链表的公共部分
  • 判断一个链表是否为回文结构

转圈打印矩阵

给定整型矩阵,按照顺时针转圈打印矩阵

class printCircleMatrix
{
public:
	printCircleMatrix();
	~printCircleMatrix();
	/*
	要宏观调控
	先打印最外面一圈,之后左上角+1,右下角-1
	继续打印,知道左上角坐标小于右下角坐标停止
	*/

	void print(int matrix[3][4], int row, int column) {
		int tR = 0;
		int tC = 0;
		int dR = row - 1;
		int dC = column - 1;
		while (tR <= dR && tC <= dC) {
			printEdage(matrix, tR++, tC++, dR--, dC--);
		}
	}

	/*
	打印边界函数
	分为三种情况
	1.矩阵为一行的情况
	2.矩阵位一列的情况
	3.不止一行一列的情况
	一定要注意边界的情况,传入的是矩阵的左上角下标和右下角下标
	左上角下标不一定为(0,0)
	*/
	void printEdage(int matrix[3][4], int tR, int tC, int dR, int dC) {
		if (tR == dR) {
			for (int i = tC; i <= dC; i++) {
				cout << matrix[tR][i] << " ";
			}
		}
		else if (tC == dC) {
			for (int i = tR; i <= dR; i++) {
				cout << matrix[i][tC];
			}
		}
		else {
			int curC = tC;  //控制横向移动
			int curR = tR;  //控制纵向移动
			while (curC != dC) {
				cout << matrix[tR][curC++] << " ";
			}
			while (curR != dR) {
				cout << matrix[curR++][dC] << " ";
			}
			while (curC != tC) {
				cout << matrix[dR][curC--] << " ";
			}
			while (curR != tR) {
				cout << matrix[curR--][tC] << " ";
			}
		}
	}
};

旋转正方形矩阵

给定一个正方形矩阵,顺时针旋转90度。

class rotateMatrix
{
public:
	rotateMatrix();
	~rotateMatrix();
	
	void rotate(int** arr, int size) {
		int tR = 0;
		int tC = 0;
		int dR = size - 1;
		int dC = size - 1;
		while (tR <= dR) {
			rotateEdge(arr, tR++, tC++, dR--, dC--);
		}
	}

	void rotateEdge(int** arr, int tR, int tC, int dR, int dC) {
		int times = dR - tR;
		int tmp = 0;
		for (int i = 0; i != times; i++) {
			tmp = arr[tR][tC + i];
			arr[tR][tC + i] = arr[dR - i][tC];
			arr[dR - i][tC] = arr[dR][tC - i];
			arr[dR][tC - i] = arr[tR + i][dC];
			arr[tR + i][dC] = tmp;
		}
	}
};

“之”字形打印矩阵

给定一个矩阵,按照之字走路打印矩阵

class zigZagPrint
{
public:
	zigZagPrint();
	~zigZagPrint();

	void print(int **arr, int row, int column) {
		int tR = 0;
		int tC = 0;
		int dR = 0;
		int dC = 0;
		int endR = row - 1;
		int endC = column - 1;
		bool fromUp = false;
		while (tR != endR + 1) {
			printLevel(arr, tR, tC, dR, dC, fromUp);
			tR = tC == endC ? tR + 1 : tR;
			tC = tC == endC ? tC : tC + 1;
			dC = dR == endR ? dC + 1 : dC;
			dR = dR == endR ? dR : dR + 1;
			fromUp = !fromUp;
		}
	}

	void printLevel(int **arr, int tR, int tC, int dR, int dC, bool fromUp) {
		if (fromUp) {
			while (tR != dR + 1) {
				cout << arr[tR++][tC--] << " ";
			}
		}
		else {
			while (dR != tR - 1) {
				cout << arr[dR--][dC++] << " ";
			}
		}
	}
};

反转单向链表

实现一个反转链表的函数

class reverseList
{
public:
	reverseList();
	~reverseList();
	
	/*
	非递归版本
	*/
	ListNode* reverse(ListNode* head) {
		if (head == NULL || head->next == NULL) {
			return head;
		}
		ListNode* pre = NULL;
		ListNode* next = NULL;
		while (head != NULL) {
			next = head->next;
			head->next = pre;
			pre = head;
			head = next;
		}
		return pre;
	}

	/*
	递归版本
	*/
	ListNode* recuision(ListNode* head) {
		if (head == NULL || head->next == NULL) {
			return head;
		}
		ListNode* reverseHead = recuision(head);
		head->next->next = head;
		head->next = NULL;
		return reverseHead;
	}
};

打印两个有序链表的公共部分

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
		val(x), next(NULL) {
	}
};

class printCommonPart
{
public:
	printCommonPart();
	~printCommonPart();
	
	void print(ListNode* head1, ListNode* head2) {
		vector<int> tmp;
		ListNode* node1 = head1;
		ListNode* node2 = head2;
		while (node1 != NULL && node2 != NULL) {
			if (node1->val < node2->val) {
				node1 = node1->next;
			}
			else if (node1->val > node2->val) {
				node2 = node2->next;
			}
			else {
				tmp.push_back(node1->val);
				node1 = node1->next;
				node2 = node2->next;
			}
		}
		for (int i = 0; i < tmp.size(); i++) {
			cout << tmp[i] << " ";
		}
	}
};

判断一个链表是否为回文结构

struct ListNode
{
	int val;
	struct ListNode* next;
};

class isPalindromeList
{
public:
	isPalindromeList();
	~isPalindromeList();
	
	//空间O(N)
	bool isPalindrome1(ListNode* head) {
		stack<int> tmp;
		ListNode* cur = head;
		while (cur != NULL) {
			tmp.push(cur->val);
			cur = cur->next;
		}
		cur = head;
		while (cur != NULL) {
			if (cur->val != tmp.top()) {
				return false;
			}
			else {
				tmp.pop();
				cur = cur->next;
			}
		}
		return true;
	}

	//空间O(N/2)
	/*
	定义两个指针,一个快指针,一个慢指针
	快指针一次走两步,慢指针一次走一步
	当快指针走到最后,慢指针正好中间,当链表node个数为奇数和偶数时,走到的位置不一样,可以自己画图搞清楚
	把后半段压入栈,一次比较
	*/
	bool isPalindrome2(ListNode* head) {
		if (head == NULL || head->next == NULL) {
			return true;
		}
		ListNode* slow = head;
		ListNode* fast = head;
		while (slow != NULL && fast != NULL) {
			slow = slow->next;
			fast = fast->next->next;
		}
		stack<int> tmp;
		while (slow != NULL) {
			tmp.push(slow->val);
			slow = slow->next;
		}
		slow = head;
		while (!tmp.empty()) {
			if (slow->val != tmp.top()) {
				return false;
			}
			else {
				tmp.pop();
				slow = slow->next;
			}
		}
		return true;
	}

	//空间O(1)
	/*
	定义两个指针,一个快指针,一个慢指针
	快指针一次走两步,慢指针一次走一步
	当快指针走到最后,慢指针正好中间,当链表node个数为奇数和偶数时,走到的位置不一样,可以自己画图搞清楚
	将后半段链表反转
	然后依次比较
	最后,别忘了将链表恢复原来的样子
	*/
	bool isPalindrome3(ListNode* head) {
		if (head == NULL || head->next == NULL) {
			return true;
		}
		ListNode* cur = head;
		ListNode* fast = head;
		while (fast != NULL) {
			cur = cur->next;
			fast = fast->next->next;
		}
		ListNode* pre = NULL;
		while (cur != NULL) {
			ListNode* next = cur->next;
			cur->next = pre;
			pre = cur;
			cur = next;
		}
		ListNode* last = pre;
		cur = head;
		bool isP = true;
		while (last != NULL) {
			if (cur->val != last->val) {
				isP = false;
				break;
			}
			cur = cur->next;
			last = last->next;
		}
		cur = pre;
		pre = NULL;
		while (cur != NULL) {
			ListNode* next = cur->next;
			cur->next = pre;
			pre = cur;
			cur = next;
		}
		return isP;
	}
};

参考

牛客网左程云算法课

猜你喜欢

转载自blog.csdn.net/weixin_39953502/article/details/79727333