概述
题号 | 题目 | 说明 |
1 | Two Sum 两数之和 | 暴利 / map查找 |
9 | Palindrome Number 验证回文数字 | |
11 | Container With Most Water 装最多水的容器 | |
26 | Remove Duplicates from Sorted Array 有序数组中去除重复项 | |
27 | Remove Element 移除元素 | |
33 | Search in Rotated Sorted Array 在旋转有序数组中搜索 | 二分搜索 |
34 | Find First and Last Position of Element in Sorted Array 搜索一个范围 | 二分搜索 |
35 | Search Insert Position 搜索插入位置 | 二分搜索 |
41 | First Missing Positive 首个缺失的正数 | |
42 | Trapping Rain Water 收集雨水 | |
56 | Merge Intervals 合并区间 | |
59 | Spiral Matrix II 螺旋矩阵之二 | |
66 | Plus One 加一运算 | |
80 | Remove Duplicates from Sorted Array II 有序数组中去除重复项之二 | |
81 | Search in Rotated Sorted Array II在旋转有序数组中搜索之二 | |
84 | Largest Rectangle in Histogram 直方图中最大的矩形 | |
88 | Merge Sorted Array 合并排序的数组 | |
153 | Find Minimum in Rotated Sorted Array 寻找旋转有序数组的最小值 | |
154 | Find Minimum in Rotated Sorted Array II 寻找旋转有序数组的最小值之二 | |
167 | Two Sum II - Input array is sorted 两数之和之二 - 输入数组有序 | |
169 | Majority Element 求众数 |
1. [LeetCode] Two Sum 两数之和
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
暴力搜索的方法是遍历所有的两个数字的组合,然后算其和,这样虽然节省了空间,但是时间复杂度高。为了提高时间的复杂度,需要用空间来换,可以使用map存数据,首先遍历一遍存入map,再次遍历使用key查找,而且注意的时不能是同一个下标。
func twoSum(nums []int, target int) []int {
var mapNumbers = make(map[int]int)
for i := 0; i < len(nums); i++ {
mapNumbers[nums[i]] = i
}
for i := 0; i < len(nums); i++ {
another := target - nums[i]
if val, ok := mapNumbers[another]; ok {
if i == val {
continue
}
return []int{i, val}
}
}
return []int{}
}
9. Palindrome Number 验证回文数字
可以使用原反转与原来数值对比,注意的情况,负数直接false,最后一位是0情况也是false,还有溢出的情况
11. Container With Most Water 装最多水的容器
func maxArea(height []int) int {
var left, right, max = 0, len(height) - 1, 0
for left < right {
var cur int
if height[left] < height[right] {
cur = height[left]
left++
} else {
cur = height[right]
right--
}
curArea := cur * (right - left + 1)
if max < curArea {
max = curArea
}
}
return max
}
26. Remove Duplicates from Sorted Array 有序数组中去除重复项
使用快慢指针来记录遍历的坐标,最开始时两个指针都指向第一个数字,如果两个指针指的数字相同,则快指针向前走一步,如果不同,则两个指针都向前走一步,这样当快指针走完整个数组后,慢指针当前的坐标加1就是数组中不同数字的个数
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if (nums.empty()) return 0;
int pre = 0, cur = 0, n = nums.size();
while (cur < n) {
if (nums[pre] == nums[cur]) ++cur;
else nums[++pre] = nums[cur++];
}
return pre + 1;
}
};
27. [LeetCode] Remove Element 移除元素
Given an array and a value, remove all instances of that value in place and return the new length.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
定义一个变量用来计数,遍历原数组,如果当前的值和给定值不同,我们就把当前值覆盖计数变量的位置,并将计数变量加1
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int res = 0;
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] != val) nums[res++] = nums[i];
}
return res;
}
};
33. Search in Rotated Sorted Array 在旋转有序数组中搜索
关键在于获得了中间数后,判断下面要搜索左半段还是右半段
- 如果中间的数小于最右边的数,则右半段是有序的
- 若中间数大于最右边数,则左半段是有序的,
func search(nums []int, target int) int {
var left, right = 0, len(nums) - 1
for left <= right {
var mid = (left + right) / 2
if nums[mid] == target {
return mid
} else if nums[mid] > nums[right] { // left
if target >= nums[left] && target < nums[mid] {
right = mid - 1
} else {
left = mid + 1
}
} else { // right
if target > nums[mid] && target <= nums[right] {
left = mid + 1
} else {
right = mid - 1
}
}
}
return -1
}
34. Find First and Last Position of Element in Sorted Array 搜索一个范围
限定了时间复杂度为O(logn),这是典型的二分查找法的时间复杂度。思路是首先对原数组使用二分查找法,找出其中一个目标值的位置,然后向两边搜索找出起始和结束的位置
使用两次二分查找法,第一次找到左边界,第二次调用找到右边界即可
主要在于处理右边界问题
func searchRange(nums []int, target int) []int {
var left, right = 0, len(nums) - 1
var res []int
if len(nums) <= 0 {
return []int{-1, -1}
}
for left < right {
var mid = (left + right) / 2
if nums[mid] < target {
left = mid + 1
} else {
right = mid
}
}
if nums[left] != target {
return []int{-1, -1}
}
fmt.Printf("left: %vn", left)
res = append(res, left)
right = len(nums)
for left < right {
var mid = (left + right) / 2
fmt.Printf("mid: %vn", mid)
if nums[mid] > target {
right = mid
} else {
left = mid + 1
}
}
res = append(res, right-1)
return res
}
35. [LeetCode] Search Insert Position 搜索插入位置
遍历一遍原数组,若当前数字大于或等于目标值,则返回当前坐标,如果遍历结束了,说明目标值比数组中任何一个数都要大,则返回数组长度n即可
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] >= target) return i;
}
return nums.size();
}
};
二分搜索法
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if (nums.back() < target) return nums.size();
int left = 0, right = nums.size() - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) left = mid + 1;
else right = mid;
}
return right;
}
};
func searchInsert(nums []int, target int) int {
var left, right = 0, len(nums) - 1
for left <= right {
var mid = (left + right) / 2
if nums[mid] == target {
return mid
} else if nums[mid] < target {
left = mid + 1
} else {
right = mid - 1
}
}
return left
}
41. First Missing Positive 首个缺失的正数
利用正整数与下标之间的关系,假设如果现在的数组里有4个数,分别是1,2,4,5,那么,如果他们按照顺序排列起来我们就可以直接从头到尾扫一遍,通过比较nums[i] 和 下标i的关系,就知道哪个正数缺失,当第一次出现nums[i] != i+1时,就说明i+1是第一个缺失的正整数。
func firstMissingPositive(nums []int) int {
var n = len(nums)
for i:=0; i<n; i++ {
for nums[i] > 0 && nums[i] <= n && nums[i] != i+1 && nums[nums[i]-1] != nums[i] {
nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]
}
}
for i:=0; i<n; i++ {
if nums[i] != i+1 {
return i+1
}
}
return n+1
}
42. Trapping Rain Water 收集雨水
-
如果较小值是left指向的值,则从左向右扫描
-
如果较小值是right指向的值,则从右向左扫描
-
若遇到的值比当较小值小,则将差值存入结果
-
如遇到的值大,则重新确定新的窗口范围
func trap(height []int) int {
var left, right, res = 0, len(height)-1, 0
var min = func(a, b int) int {
if a < b {
return a
}
return b
}
for left < right {
var min = min(height[left], height[right])
if height[left] == min {
left++
for left < right && height[left] < min {
res += min - height[left]
left++
}
} else {
right--
for left < right && height[right] < min {
res += min - height[right]
right--
}
}
}
return res
}
56. Merge Intervals 合并区间
- 起始位置和结束位置分别存到了两个不同的数组starts和ends中,然后分别进行排序
- 判断不连续就加入结果中
func merge(intervals []Interval) []Interval {
var n, s = len(intervals), 0
var res, starts, ends = make([]Interval, 0), make([]int, n), make([]int, n)
for i:=0; i<n; i++ {
starts[i] = intervals[i].Start
ends[i] = intervals[i].End
}
sort.Ints(starts)
sort.Ints(ends)
for i:=0; i<n; i++ {
if i==n-1 || starts[i+1] > ends[i] {
res = append(res, Interval{starts[s], ends[i]})
s = i + 1
}
}
return res
}
59. Spiral Matrix II 螺旋矩阵之二
func generateMatrix(n int) [][]int {
var res = make([][]int, 0)
for i:=0; i<n; i++ {
var temp = make([]int, n)
res = append(res, temp)
}
var up, down, left, right, val = 0, n - 1, 0, n-1, 1
for {
for j:=left; j<=right; j++ {
res[up][j] = val
val++
}
up++
if up > down {break}
for i:=up; i<=down; i++ {
res[i][right] = val
val++
}
right--
if right<left {break}
for j:=right; j>=left; j-- {
res[down][j] = val
val++
}
down--
if down < up {break}
for i:=down; i>=up; i-- {
res[i][left] = val
val++
}
left++
if left > right {break}
}
return res
}
66. Plus One 加一运算
func plusOne(digits []int) []int {
for i:=len(digits)-1; i>=0; i-- {
if digits[i] == 9 {
digits[i] = 0
} else {
digits[i] += 1
return digits
}
}
if digits[0] == 0 {
digits = append([]int{1}, digits...)
}
return digits
}
80. Remove Duplicates from Sorted Array II 有序数组中去除重复项之二
Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?For example,
Given sorted array A =[1,1,1,2,2,3]
,Your function should return length =
5
, and A is now[1,1,2,2,3]
.
使用两个指针prev和curr,判断A[curr]是否和A[prev]、A[prev-1]相等,如果相等curr指针继续向后遍历,直到不相等时,将curr指针指向的值赋值给A[prev+1],这样多余的数就都被交换到后面去了。最后prev+1值就是数组的长度
func removeDuplicates(nums []int) int {
n := len(nums)
if n <= 2 {
return n
}
var (
pre = 1
cur = 2
)
for i := cur; i < n; i++ {
if nums[cur] == nums[pre] && nums[cur] == nums[pre-1] {
cur++
} else {
pre += 1
nums[pre] = nums[cur]
cur += 1
}
}
return pre + 1
}
81. Search in Rotated Sorted Array II在旋转有序数组中搜索之二
出现来面两种情况,[3 1 1] 和 [1 1 3 1],对于这两种情况中间值等于最右值时,目标值3既可以在左边又可以在右边,那怎么办么,对于这种情况其实处理非常简单,只要把最右值向左一位即可继续循环,如果还相同则继续移,直到移到不同值为止
func search(nums []int, target int) bool {
var left, right = 0, len(nums) - 1
for left <= right {
var mid = (left + right) / 2
if nums[mid] == target {
return true
} else if nums[mid] < nums[right] {
if nums[mid] < target && nums[right] >= target {
left = mid + 1
} else {
right = mid - 1
}
} else if nums[mid] > nums[right] {
if nums[left] <= target && nums[mid] > target {
right = mid - 1
} else {
left = mid + 1
}
} else {
right--
}
}
return false
}
84. Largest Rectangle in Histogram 直方图中最大的矩形
局部峰值,然后向前遍历所有的值,算出共同的矩形面积,每次对比保留最大值
func largestRectangleArea(heights []int) int {
var res = 0
var min = func(a, b int) int {
if a < b {
return a
}
return b
}
var max = func(a, b int) int {
if a > b {
return a
}
return b
}
for i := 0; i < len(heights); i++ {
if i+1 < len(heights) && heights[i] <= heights[i+1] {
continue
}
var minH = heights[i]
for j := i; j >= 0; j-- {
minH = min(minH, heights[j])
var area = (i - j + 1) * minH
res = max(res, area)
}
}
return res
}
88. Merge Sorted Array 合并排序的数组
func merge(nums1 []int, m int, nums2 []int, n int) {
var i, j, k = m - 1, n - 1, m + n - 1
for i >= 0 && j >= 0 {
if nums1[i] > nums2[j] {
nums1[k] = nums1[i]
i--
} else {
nums1[k] = nums2[j]
j--
}
k--
}
for j >= 0 {
nums1[k] = nums2[j]
k--
j--
}
}
153. Find Minimum in Rotated Sorted Array 寻找旋转有序数组的最小值
中间那个数,然后和left指的数比较,如果中间的数大,则继续二分查找右半段数组,反之查找左半段。终止条件是当左右两个指针相邻,返回小的那个。
func findMin(nums []int) int {
var left, right = 0, len(nums) - 1
if right < 0 {return 0}
if right == 0 {return nums[0]}
if nums[left] < nums[right] {
return nums[left]
}
var min = func(a, b int) int {
if a < b {return a}
return b
}
for left < right-1 {
var mid = (left + right) / 2
if nums[left] < nums[mid] {
left = mid
} else {
right = mid
}
}
return min(nums[left], nums[right])
}
154. Find Minimum in Rotated Sorted Array II 寻找旋转有序数组的最小值之二
func findMin(nums []int) int {
var left, right = 0, len(nums) - 1
if right < 0 {return 0}
var res = nums[0]
var min = func(a, b int) int {
if a < b {return a}
return b
}
for left < right-1 {
var mid = (left + right) / 2
if nums[left] < nums[mid] {
res = min(res, nums[left])
left = mid+1
} else if nums[left] > nums[mid]{
res = min(res, nums[right])
right = mid
} else {
left++
}
}
return min(nums[left], min(nums[right], res))
}
167. Two Sum II - Input array is sorted 两数之和之二 - 输入数组有序
O(n)的解法,left指向开头,right指向末尾,然后向中间遍历,如果指向的两个数相加正好等于target的话,直接返回两个指针的位置即可,若小于target,left右移一位,若大于target,right左移一位
func twoSum(numbers []int, target int) []int {
var left, right = 0, len(numbers) - 1
for left < right {
var sum = numbers[left] + numbers[right]
if sum == target {
return []int{left+1, right+1}
} else if sum > target {
right--
} else {
left--
}
}
return []int{-1, -1}
}
169. Majority Element 求众数
func majorityElement(nums []int) int {
var res, cnt = 0, 0
for i:=0; i<len(nums); i++ {
if cnt == 0 {
res = nums[i]
cnt++
} else {
if nums[i] == res {
cnt++
} else {
cnt--
}
}
}
return res
}
347. Top K Frequent Elements
前K个高频元素
Given a non-empty array of integers, return the k most frequent elements.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2]
Example 2:
Input: nums = [1], k = 1 Output: [1]
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
2. leetcode 约瑟夫问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void yueSeFu(int a[], int n, int m) {
if (a==NULL || n<=0) return;
int count = n;
int i = 0; //n
int j = 0; //m
while (count != 0) {
if (a[i] != 0) {
j++;
if (j%m == 0) {
j = 0;
printf("%dn", a[i]);
a[i] = 0;
count--;
}
}
i++;
if (i%n == 0)
i = 0;
}
}
int main()
{
int n, m, i;
scanf("%d %d", &n, &m);
int *pN = (int *)malloc(sizeof(int) * (n));
if (pN == NULL)
exit(-1);
for (i=0; i<n; i++) {
pN[i] = i + 1;
}
yueSeFu(pN, n, m);
return 0;
}
3. leetcode KMP
求模式 a b a a b c a c的next函数的算法:
因为已知next(1)=0,只要找出next(j+1)与next(j)之间的关系,就可以求出模式串所有next。
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">next初始算法::::</span>
(1)next[j] = 0 j=1
(2)设next[j]=k, 于是有p(1)...p(k-1) = p(j-k+1)...p(j-1)
若p(k) = p(j) 必然有<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">p(1)...p(k-1)p(k) = p(j-k+1)...p(j-1)p(j) next[j+1] = next[j] + 1 = k +1</span>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;"> 若不等 </span>
void get_next(sstring T, int &next[])
{
//求模式串T的next函数值并存入数组next。
j=1; k=next[j]=0;
while (j<T[0]) { //计算next(j)从next(2)到next(T[0]),T[0]是T的长度
//但并不意味着只循环m-1次,因为在循环体中j的值可能不发生变化
if (k==0||T[j]==T[k])// 没有重叠真子串和(有重叠真子串但T[j]==T[k])时//都应该得出next(j+1)的值
next[++j]=++k;
else k=next(k);//否则,得不出next(j+1)的值,所以j不变,k退回到next(k),重复匹配。
}
利用next值表进行匹配的过程:
假设以i和j分别指示主串和模式串中正待比较的字符,若si=tj ,则i和j分别增1,否则,i不变,而j退回到next[j]的位置再比较,若j退回到值为0(即模式的第一个字符失配),则将模式继续向右滑动一个位置,即从主串的下一个字符si+1起和模式重新开始匹配。
int index_KMP(sstring s, sstring t, int pos)
{
//利用模式串的next函数求t在主串s中第pos个字符之后的位置的KMP算法,
//t非空,1<=pos<=strlength(s)
i=pos; j=1;
while(i<=s[0]&&j<=t[0])
{
if (j==0||s[i]==t[j]){++i;++j;}
else j=next[j];
}
if (j>t[0]) return i-t[0];
else return 0;
}//index_kmp
最后
以上就是落后小鸽子为你收集整理的【leetcode算法面试】leetcode题目4-数组 1. [LeetCode] Two Sum 两数之和9. Palindrome Number 验证回文数字 26. Remove Duplicates from Sorted Array 有序数组中去除重复项27. [LeetCode] Remove Element 移除元素33. Search in Rotated Sorted Array 在旋转有序数组中搜索34. Find First and Last Position of的全部内容,希望文章能够帮你解决【leetcode算法面试】leetcode题目4-数组 1. [LeetCode] Two Sum 两数之和9. Palindrome Number 验证回文数字 26. Remove Duplicates from Sorted Array 有序数组中去除重复项27. [LeetCode] Remove Element 移除元素33. Search in Rotated Sorted Array 在旋转有序数组中搜索34. Find First and Last Position of所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复