最近,唐尚珺称 C语言 课程有点费脑筋。但是这对于初学者来说其实十分正常,毕竟 C语言 不像 python 一样一行 print 就可以在终端输出字符串。
C语言 是一个古老的、最早被发明用于替代 B语言 的编译型高级编程语言。Linux内核中的大部分代码都是 C语言 写的。
C语言 也是许多大学大一的通识教育课程之一。但是由于很多大学 C语言 教材的老旧,加上大多初学者根本没接触过编程,因此许多人会觉得有困难。
笔者就是在学习 C语言 之后有了一定的编程基础后,进行 C++ 或 java 等语言的学习,C++即支持面向对象编程也支持面向过程编程。
因此在本文的中我会附上 C语言 基础文件操作的 demo 以供参考。
C语言 基础文件操作 demo:
CSDN - 本博客 C语言 基础文件操作demo和说明下载
快捷下载本博客资源:
今天的题目:
题目描述:
题号:153
已知一个长度为 n
的数组,预先按照升序排列,经由 1
到 n
次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7]
在变化后可能得到:
-
若旋转
4
次,则可以得到[4,5,6,7,0,1,2]
-
若旋转
7
次,则可以得到[0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]]
旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]]
。
给你一个元素值 互不相同 的数组 nums
,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n)
的算法解决此问题。
解题思路:
思路一:二分查找 + 判断最小值在哪半边
设置两个指针,分别指向数组的起始位置和结束位置。
然后,我们取数组中间位置的元素,与结束位置的元素进行比较。
如果中间位置的元素大于结束位置的元素,说明最小值在右半部分,因为右半部分被旋转到了前面;
否则,最小值在左半部分或者就是中间位置的元素。我们根据这个判断不断缩小搜索范围,直到找到最小值。
特殊说明:为什么代码中返回的是左指针,而不是右指针
当我们确定最小值位于左半部分时,我们会将右指针移动到中间位置,而左指针保持不变。此时,右指针指向的值并不是最小值,而是用于帮助确定最小值位置的一个参照点。
随着搜索范围的不断缩小,左指针和右指针会逐渐靠近。最终,当左指针和右指针相邻时,搜索范围就只剩下一个元素,这个元素就是最小值。由于此时左指针指向这个最小值的位置,因此我们返回nums[left]
是正确的。
另一方面,如果我们返回右指针指向的值,那么在最后一步迭代中,由于右指针已经移动到左指针的相邻位置,它指向的并不是最小值,而是最小值的右侧元素(在升序数组中)。
时间复杂度:O(log n)
空间复杂度:O(1)
C++
// C++
class Solution {
public:
int findMin(vector<int>& nums) {
int left = 0;
int right = nums.size() - 1;
while(left < right) {
int mid = (right - left)/2 + left;
if(nums[mid] > nums[right]) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[left];
}
};
go
// go
func findMin(nums []int) int {
left, right := 0, len(nums) - 1
for left < right {
mid := (right - left)/2 + left
if nums[mid] > nums[right] {
left = mid + 1
} else {
right = mid
}
}
return nums[left]
}