难度:困难
题目要求:
给定一个未排序的整数数组nums
,找出其中没有出现的最小的正整数。
示例1:
输入:nums = [1,2,0]
输出:3
示例2:
输入:nums = [3,4,-1,1]
输出:2
示例3:
输入:nums = [7,8,9,11,12]
输出:1
题解:
先过滤负数和零,然后进行升序排列,得到的数列如果都大于
1
,那么直接返回1
,其他的情况就是集合内相邻的两个数相减,如果结果大于1
,就说明缺失的正数在这两个数之间,返回小值加一即可,如果上述条件都不符合,就返回最大值加一
想法代码
class Solution
{
public static void Main(String[] args)
{
Solution solution = new Solution();
int[] nums = { 1, 2, 0 };
int res = solution.FirstMissingPositive(nums);
Console.WriteLine(res);
}
public int FirstMissingPositive(int[] nums)
{
var li = new List(nums).Where(c => c > 0).ToList();
if (li.Count < 1)
{
return 1;
}
li.Sort();
if (li.First() > 1)
{
return 1;
}
for (int i = 0; i < li.Count - 1; i++)
{
var c = li[i + 1] - li[i];
if (c > 1)
{
return li[i] + 1;
}
}
return li[li.Count - 1] + 1;
}
}
难度:困难
题目要求:
给定 n
个非负整数表示每个宽度为 1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
示例2:
输入:height = [4,2,0,3,2,5]
输出:9
题解:
下标 i i i 处的雨水能达到的高度等于其两边的最大高度的最小值,下标 i i i 处的雨水能达到的高度与 h e i g h t [ i ] height[i] height[i] 之差即为下标 i i i 处的雨水量
创建两个长度为 n n n 的数组 l e f t H e i g h t leftHeight leftHeight 和 r i g h t H e i g h t rightHeight rightHeight,对于 0 ≤ i < n , l e f t H e i g h t [ i ] 0\leq i
0≤i<n,leftHeight[i] 表示 h e i g h t height height 在下标范围 [ 0 , i ] [0,i] [0,i] 内的最大元素, r i g h t H e i g h t [ i ] rightHeight[i] rightHeight[i] 表示 r i g h t right right 在下标范围内 [ i , n − 1 ] [i,n-1] [i,n−1] 内的最大元素
计算方法如下:
- 对于 l e f t H e i g h t , l e f t H e i g h t [ 0 ] = h e i g h t [ 0 ] leftHeight,leftHeight[0]=height[0] leftHeight,leftHeight[0]=height[0],当 0 ≤ i < n 0\leq i
0≤i<n 时, l e f t H e i g h t [ i ] = m a x ( l e f t H e i g h t [ i − 1 ] , h e i g h t [ i ] leftHeight[i]=max(leftHeight[i-1],height[i] leftHeight[i]=max(leftHeight[i−1],height[i],从左到右依次计算 l e f t H e i g h t leftHeight leftHeight 的值- 对于 r i g h t H e i g h t , r i g h t H e i g h t [ n − 1 ] = h e i g h t [ n − 1 ] rightHeight,rightHeight[n-1]=height[n-1] rightHeight,rightHeight[n−1]=height[n−1],当 0 ≤ i < n − 1 0\leq i
0≤i<n−1 时, r i g h t H e i g h t [ i ] = m a x ( r i g h t H e i g h t [ i + 1 ] , h e i g h t [ i ] rightHeight[i]=max(rightHeight[i+1],height[i] rightHeight[i]=max(rightHeight[i+1],height[i],从右到左依次计算 r i g h t H e i g h t rightHeight rightHeight 的值
最后数组 l e f t H e i g h t leftHeight leftHeight 和 r i g h t H e i g h t rightHeight rightHeight 之后,即可计算每个下标的雨水量,下标 i i i 处的雨水能达到的高度是 m i n ( l e f t H e i g h t [ i ] , r i g h t H e i g h t [ i ] ) min(leftHeight[i],rightHeight[i]) min(leftHeight[i],rightHeight[i]),因此下标 i i i 处的雨水量是 m i n ( l e f t H e i g h t [ i ] , r i g h t H e i g h t [ i ] ) − h e i g h t [ i ] min(leftHeight[i],rightHeight[i])-height[i] min(leftHeight[i],rightHeight[i])−height[i]。遍历每一个下标,计算每个下标的雨水量,即可得到能接的雨水总量
想法代码:
class Solution
{
public static void Main(String[] args)
{
int[] height = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
Solution solution = new Solution();
int res = solution.Trap(height);
Console.WriteLine(res);
}
public int Trap(int[] height)
{
int n = height.Length;
int[] leftHeight = new int[n];
leftHeight[0] = height[0];
for (int i = 1; i < n; i++)
{
leftHeight[i] = Math.Max(leftHeight[i - 1], height[i]);
}
int[] rightHeight = new int[n];
rightHeight[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; i--)
{
rightHeight[i] = Math.Max(rightHeight[i + 1], height[i]);
}
int amout = 0;
for (int i = 0; i < n; i++)
{
amout += Math.Min(leftHeight[i], rightHeight[i]) - height[i];
}
return amout;
}
}