剑指offer---栈和队列、查找和排序

本文探讨使用两个栈实现队列的方法及旋转数组中寻找最小元素的高效算法。通过具体代码实例,详细解析了如何利用栈的特性完成队列的基本操作,以及在旋转数组中应用二分查找法快速定位最小值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开宗明义:本系列基于牛客网剑指offer,刷题小白,一天两道我快乐!旨在理解和交流,重在记录,望各位大牛指点!


牛客网-剑指offer



1、栈和队列

描述用两个栈来实现一个队列,完成队列的push和pop操作。队列的元素为int类型

思路

  1. 栈:先进后出;队列:先进先出
  2. Stack1负责入栈,Stack2负责出栈
  3. 将Stack1的出栈入Stack2,再Stack2出栈就是先入先出了

测试代码:

class Solution {
public:
	void push(int node) {
		stack1.push(node);	//入栈	
	}

	int pop() {
		int temp;
		if (stack2.empty()) {	//如果这个栈未空
			while (!stack1.empty()) {
                int t=stack1.top();
                stack1.pop();
				stack2.push(t);	//后进的入栈栈顶先入
				
			}
		}
		//如果这个栈不为空
		temp = stack2.top();  //这时候栈2变成了后进的先入,先进的后入
		stack2.pop();
		return temp;
	}

private:
	stack<int> stack1;	//用于存储push的元素
	stack<int> stack2;	//用于倒转stack的元素,以生成队列
};

2、旋转数组的最小数字

描述把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出所有的元素都大于0,若数组大小为0,请返回0


思路1直接把这个vector调用STL的sort排序函数排序,然后输出第一个元素就可以了,就是最小值

测试代码:

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        sort(rotateArray.begin(),rotateArray.end()); 
        return rotateArray[0];
    }
};

思路2二分查找法

  1. 第一点,由题意,这个数组是递增的;
  2. 设定 m i d = l o w + ( h i g h − l o w ) / 2 mid=low+(high-low)/2 mid=low+(highlow)/2;
  3. 设定两个标签,初始化的时候一个指向头 l e f t left left,一个指向尾 r i g h t right right
  4. l e f t &lt; r i g h t left&lt;right left<right 的前提下,考虑下面三种情况:
  5. r o t a t e A r r a y [ l e f t ] &lt; r o t a t e A r r a y [ m i d ] rotateArray[left] &lt; rotateArray[mid] rotateArray[left]<rotateArray[mid] 说明前面是递增的,那么旋转了,最小值在后面,那么 l e f t = m i d + 1 left=mid+1 left=mid+1;
  6. r o t a t e A r r a y [ m i d ] &lt; r o t a t e A r r a y [ r i g h t ] rotateArray[mid] &lt; rotateArray[right] rotateArray[mid]<rotateArray[right] 说明后面是递增的,那么最小值在前面,那么这时候更新 r i g h t right right;
  7. 这边更新 r i g h t right right ,更新 r i g h t = m i d right = mid right=mid,而不是 r i g h t = m i d − 1 right = mid -1 right=mid1,因为如果最后只剩两个数 [ 4 , 6 ] [4,6] [4,6] ,那么 l e f t = 4 , r i g h t = 6 left=4,right =6 left=4,right=6,这时候 m i d mid mid 指向下标靠前的数字。

测试代码:

//C++ 二分法
#include <vector>
using namespace std;

class Solution {
public:
	int minNumberInRotateArray(vector<int> rotateArray) {
		if (rotateArray.empty()) 
			return 0;

		int left = 0;
		int right = rotateArray.size() - 1;
		while (left < right) {
			//确认子数组是否是类似1,1,2,4,5,..,7的非递减数组
			if (rotateArray[left] < rotateArray[right])
				return rotateArray[left];

			int mid = left + (right - left) / 2;
			//如果左半数组为有序数组.说明旋转了,最小元素肯定在右边
			if (rotateArray[left] < rotateArray[mid])
				left = mid + 1;
			//如果右半数组为有序数组
			else 
				if (rotateArray[mid] < rotateArray[right])
					right = mid;
			//否则,rotateArray[left] == rotateArray[mid] == rotateArray[right]
			else {
				++left;
			}
		}
		return rotateArray[left];
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值