和 for
循环相比,while
循环是一种更强大循环方式。当我们在使用 for
循环时,通常我们会提前知道循环的次数、以及循环的结束条件。
当场景满足以下条件时,我们通常会优先考虑使用 while
循环:
例如,我们需要找到一个数组中,最大的那个值,我们可以使用 for
循环来实现:
10
function
max
(
arr
:
number
[])
:
number
{
20
// 首先定义一个临时变量,用来存储最大值
30
let
max
=
arr[
0
];
40
// 然后定义一个索引指针,从 1 开始,因为我们已经把第一个元素赋值给了 max,递增移动到数组最后一位
50
for
(
let
i
=
1
; i
<
arr.
length
; i
++
) {
60
// 然后在索引指针移动的过程中,不断的比较当前元素和最大值,如果当前元素大于最大值,则替换
70
if
(arr[i]
>
max) {
80
max
=
arr[i];
90
}
10
}
11
return
max;
12
}
我们使用 while 循环来实现:
10
function
max
(
arr
:
number
[])
:
number
{
20
// 首先定义一个临时变量,用来存储最大值
30
let
max
=
arr[
0
];
40
// 然后定义一个索引指针
50
let
i
=
1
;
60
// 当满足条件时,进入循环体,否则退出循环
70
while
(i
<
arr.
length
) {
80
if
(arr[i]
>
max) {
90
max
=
arr[i];
10
}
11
// while 循环通常在循环体的最结尾,编写循环迭代的方式
12
i
++
;
13
}
14
return
max;
15
}
可以看到,while 循环会把初始化定义在循环的外面,然后关注循环结束条件,最后在循环体的结尾编写迭代方式。
由于我们可以把循环的迭代条件放到循环体内部来实现,所以,while 循环通常可以应对更复杂的情况。
接下来,我们来看一个稍微复杂一点的案例
已知一个已经排好序 的数组,从该数组中,找到两个数之和等于目标值
由于要找到两个数,所以我们可以使用双指针 来解决这个问题,一个指针指向数组的第一个元素,另一个指针指向数组的最后一个元素。
双指针分别从数组的两端往中间移动,每移动一次算出两数和,直到找到两个数之和等于目标值
10
// 在已排序数组中找出两数之和等于目标值
20
function
twoSumSorted
(
arr
,
target
) {
30
// 定义两个指针
40
let
left
=
0
;
50
let
right
=
arr.
length
-
1
;
60
70
// 定义循环结束条件
80
while
(left
<
right) {
90
const
sum
=
arr[left]
+
arr[right];
10
if
(sum
===
target) {
11
// 找到目标值,结束函数执行
12
return
[left, right];
13
}
14
// 定义迭代条件
15
if
(sum
<
target) {
16
left
++
;
17
}
else
{
18
right
--
;
19
}
20
}
21
return
[];
22
}
注意这里的迭代条件,由于数组是已经排好序 的,因此两数之和的变化趋势是:
当两数之和小于目标值时,我们需要让两数之和变大,此时移动左指针 当两数之和大于目标值时,我们需要让两数之和变小,此时移动右指针
如果题目中是无序的数组,我们可以先对数组进行排序,然后再使用双指针来解决这个问题
当然,我们也可以使用 for 循环来实现:
10
function
twoSumSorted
(
arr
,
target
) {
20
let
left
=
0
;
30
let
right
=
arr.
length
-
1
;
40
50
for
(; left
<
right;) {
60
const
sum
=
arr[left]
+
arr[right];
70
if
(sum
===
target) {
80
return
[left, right];
90
}
10
if
(sum
<
target) {
11
left
++
;
12
}
else
{
13
right
--
;
14
}
15
}
16
return
[];
17
}
从一组正整数数组中,找出和为 k 的连续子数组的最大长度