Skip to content

Commit 9f32524

Browse files
committed
1000题了惹
1 parent 9c48100 commit 9f32524

File tree

3 files changed

+240
-0
lines changed

3 files changed

+240
-0
lines changed

indexes/力扣千题.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@
394394
* [949. 给定数字能组成的最大时间](../problems/949.给定数字能组成的最大时间.md)
395395
* [953. 验证外星语词典](../problems/953.验证外星语词典.md)
396396
* [954. 二倍数对数组](../problems/954.二倍数对数组.md)
397+
* [958. 二叉树的完全性检验](../problems/958.二叉树的完全性检验.md)
397398
* [963. 最小面积矩形 II](../problems/963.最小面积矩形II.md)
398399
* [965. 单值二叉树](../problems/965.单值二叉树.md)
399400
* [968. 监控二叉树](../problems/968.监控二叉树.md)
@@ -596,5 +597,6 @@
596597
* [1929. 数组串联](../problems/1929.数组串联.md)
597598
* [1933. 判断字符串是否可分解为值均等的子串](../problems/1933.判断字符串是否可分解为值均等的子串.md)
598599
* [1941. 检查是否所有字符出现次数相同](../problems/1941.检查是否所有字符出现次数相同.md)
600+
* [1942. 最小未被占据椅子的编号](../problems/1942.最小未被占据椅子的编号.md)
599601
* [1952. 三除数](../problems/1952.三除数.md)
600602

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# 1942. 最小未被占据椅子的编号
2+
有 n个朋友在举办一个派对,这些朋友从 0到 n - 1编号。
3+
派对里有 无数张椅子,编号为 0到 infinity。当一个朋友到达派对时,他会占据编号最小且未被占据的椅子。
4+
5+
比方说,当一个朋友到达时,如果椅子0,1和5被占据了,那么他会占据2号椅子。
6+
当一个朋友离开派对时,他的椅子会立刻变成未占据状态。如果同一时刻有另一个朋友到达,可以立即占据这张椅子。
7+
8+
给你一个下标从 0开始的二维整数数组times,其中``times[i] = [arrivali, leavingi]``表示第 i个朋友到达和离开的时刻,
9+
同时给你一个整数``targetFriend``。所有到达时间 互不相同。
10+
11+
请你返回编号为``targetFriend``的朋友占据的 椅子编号。
12+
13+
14+
15+
示例 1:
16+
```
17+
输入:times = [[1,4],[2,3],[4,6]], targetFriend = 1
18+
输出:1
19+
解释:
20+
- 朋友 0 时刻 1 到达,占据椅子 0 。
21+
- 朋友 1 时刻 2 到达,占据椅子 1 。
22+
- 朋友 1 时刻 3 离开,椅子 1 变成未占据。
23+
- 朋友 0 时刻 4 离开,椅子 0 变成未占据。
24+
- 朋友 2 时刻 4 到达,占据椅子 0 。
25+
朋友 1 占据椅子 1 ,所以返回 1 。
26+
```
27+
示例 2:
28+
```
29+
输入:times = [[3,10],[1,5],[2,6]], targetFriend = 0
30+
输出:2
31+
解释:
32+
- 朋友 1 时刻 1 到达,占据椅子 0 。
33+
- 朋友 2 时刻 2 到达,占据椅子 1 。
34+
- 朋友 0 时刻 3 到达,占据椅子 2 。
35+
- 朋友 1 时刻 5 离开,椅子 0 变成未占据。
36+
- 朋友 2 时刻 6 离开,椅子 1 变成未占据。
37+
- 朋友 0 时刻 10 离开,椅子 2 变成未占据。
38+
朋友 0 占据椅子 2 ,所以返回 2 。
39+
```
40+
41+
提示:
42+
```
43+
n == times.length
44+
2 <= n <= 104
45+
times[i].length == 2
46+
1 <= arrivali < leavingi <= 105
47+
0 <= targetFriend <= n - 1
48+
每个arrivali时刻互不相同。
49+
```
50+
51+
## [C#]优先队列
52+
### 解题思路
53+
参考的官方解法:
54+
55+
+ 对于每一个人,它会在两个时刻影响椅子占据与否的状态:
56+
+ 在他到达时,他会选择占据编号最小的未被占据的椅子;
57+
+ 在他离开时,他会释放之前占据的椅子。
58+
+ 这两种情况分别对应以下操作:
59+
+ 查询当前未被占据的编号最小的椅子,并将该椅子移出未被占据椅子的集合;
60+
+ 查询某个人当前占据的椅子编号,并将该椅子加入未被占据的椅子中。
61+
62+
63+
C#没有优先队列,需要自己实现
64+
65+
66+
### 代码
67+
68+
```csharp
69+
public class Solution
70+
{
71+
public int SmallestChair(int[][] times, int targetFriend)
72+
{
73+
var n = times.Length;
74+
var arrive = new int[n][];
75+
var leave = new int[n][];
76+
for (var i = 0; i < n; i++)
77+
{
78+
arrive[i] = new int[2];
79+
arrive[i][0] = times[i][0];
80+
arrive[i][1] = i;
81+
leave[i] = new int[2];
82+
leave[i][0] = times[i][1];
83+
leave[i][1] = i;
84+
}
85+
86+
// 升序排列
87+
Array.Sort(arrive, (a, b) => a[0].CompareTo(b[0]));
88+
Array.Sort(leave, (a, b) => a[0].CompareTo(b[0]));
89+
90+
var pq = new PriorityQueue<int>(); //存储可用座位
91+
for (var i = 0; i < n; i++)
92+
{
93+
pq.Add(i); // n个人最多用到n个座位 起初都可用
94+
}
95+
96+
var map = new Dictionary<int, int>(); //存储人与座位
97+
var j = 0; //记录离开到哪个人
98+
foreach (var arr in arrive)
99+
{
100+
// 释放座位
101+
while (j < n && leave[j][0] <= arr[0])
102+
{
103+
pq.Add(map[leave[j][1]]);
104+
j++;
105+
}
106+
107+
int seat = pq.PopFirst(); //最小座位
108+
map.Add(arr[1], seat);
109+
if (arr[1] == targetFriend) return seat;
110+
}
111+
112+
return -1;
113+
}
114+
}
115+
116+
public class PriorityQueue<T> where T : IComparable<T>
117+
{
118+
private SortedList<T, int> list = new SortedList<T, int>();
119+
private int count = 0;
120+
121+
public void Add(T item)
122+
{
123+
if (list.ContainsKey(item)) list[item]++;
124+
else list.Add(item, 1);
125+
126+
count++;
127+
}
128+
129+
public T PopFirst()
130+
{
131+
if (Size() == 0) return default(T);
132+
T result = list.Keys[0];
133+
if (--list[result] == 0)
134+
list.RemoveAt(0);
135+
136+
count--;
137+
return result;
138+
}
139+
140+
public T PopLast()
141+
{
142+
if (Size() == 0) return default(T);
143+
int index = list.Count - 1;
144+
T result = list.Keys[index];
145+
if (--list[result] == 0)
146+
list.RemoveAt(index);
147+
148+
count--;
149+
return result;
150+
}
151+
152+
public int Size()
153+
{
154+
return count;
155+
}
156+
157+
public T PeekFirst()
158+
{
159+
if (Size() == 0) return default(T);
160+
return list.Keys[0];
161+
}
162+
163+
public T PeekLast()
164+
{
165+
if (Size() == 0) return default(T);
166+
int index = list.Count - 1;
167+
return list.Keys[index];
168+
}
169+
}
170+
171+
```
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# 958. 二叉树的完全性检验
2+
给定一个二叉树,确定它是否是一个完全二叉树。
3+
4+
百度百科中对完全二叉树的定义如下:
5+
6+
若设二叉树的深度为 h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,
7+
第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。(注:第 h 层可能包含 1~2h个节点。)
8+
9+
10+
示例 1:
11+
```
12+
输入:[1,2,3,4,5,6]
13+
输出:true
14+
解释:最后一层前的每一层都是满的(即,结点值为 {1} 和 {2,3} 的两层),且最后一层中的所有结点({4,5,6})都尽可能地向左。
15+
```
16+
示例 2:
17+
```
18+
输入:[1,2,3,4,5,null,7]
19+
输出:false
20+
解释:值为 7 的结点没有尽可能靠向左侧。
21+
```
22+
23+
提示:
24+
```
25+
树中将会有 1 到 100 个结点。
26+
```
27+
28+
### 解题思路
29+
+ 对于根节点,我们定义其编号为 1。然后,对于每个节点 v,我们将其左节点编号为 ``2 * v``,将其右节点编号为 ``2 * v + 1``
30+
+ 我们可以发现,树中所有节点的编号按照广度优先搜索顺序正好是升序。(也可以使用深度优先搜索,之后对序列排序)。
31+
+ 然后,我们检测编号序列是否为无间隔的 1, 2, 3, …,事实上,我们只需要检查最后一个编号是否正确,因为最后一个编号的值最大。
32+
33+
### 代码
34+
35+
```csharp
36+
/**
37+
* Definition for a binary tree node.
38+
* public class TreeNode {
39+
* public int val;
40+
* public TreeNode left;
41+
* public TreeNode right;
42+
* public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
43+
* this.val = val;
44+
* this.left = left;
45+
* this.right = right;
46+
* }
47+
* }
48+
*/
49+
public class Solution
50+
{
51+
public bool IsCompleteTree(TreeNode root)
52+
{
53+
var nodes = new List<(TreeNode node, int value)> {(root, 1)};
54+
var i = 0;
55+
while (i < nodes.Count)
56+
{
57+
var curNode = nodes[i];
58+
i++;
59+
if (curNode.node == null) continue;
60+
nodes.Add((curNode.node.left, curNode.value * 2));
61+
nodes.Add((curNode.node.right, curNode.value * 2 + 1));
62+
}
63+
64+
return nodes[i - 1].value == nodes.Count;
65+
}
66+
}
67+
```

0 commit comments

Comments
 (0)