[router-table] simplify `Allocate()` and random selection of ID (#8032)

This commit updates `RouterTable::Allocate()` to use Reservoir
sampling algorithm to randomly select a router ID while iterating
through the list of available IDs.
diff --git a/src/core/thread/router_table.cpp b/src/core/thread/router_table.cpp
index 722fadd..d9731bd 100644
--- a/src/core/thread/router_table.cpp
+++ b/src/core/thread/router_table.cpp
@@ -205,9 +205,11 @@
 
 Router *RouterTable::Allocate(void)
 {
-    Router *rval         = nullptr;
-    uint8_t numAvailable = 0;
-    uint8_t freeBit;
+    Router *router           = nullptr;
+    uint8_t numAvailable     = 0;
+    uint8_t selectedRouterId = Mle::kInvalidRouterId;
+
+    VerifyOrExit(mActiveRouterCount < Mle::kMaxRouters);
 
     // count available router ids
 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
@@ -219,38 +221,26 @@
         if (!IsAllocated(routerId) && mRouterIdReuseDelay[routerId] == 0)
         {
             numAvailable++;
+
+            // Randomly select a router ID as we iterate through the
+            // list using Reservoir algorithm: We replace the
+            // selected ID with current entry in the list with
+            // probably `1/numAvailable`.
+
+            if (Random::NonCrypto::GetUint8InRange(0, numAvailable) == 0)
+            {
+                selectedRouterId = routerId;
+            }
         }
     }
 
-    VerifyOrExit(mActiveRouterCount < Mle::kMaxRouters && numAvailable > 0);
+    VerifyOrExit(selectedRouterId != Mle::kInvalidRouterId);
 
-    // choose available router id at random
-    freeBit = Random::NonCrypto::GetUint8InRange(0, numAvailable);
-
-    // allocate router
-#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
-    for (uint8_t routerId = mMinRouterId; routerId <= mMaxRouterId; routerId++)
-#else
-    for (uint8_t routerId = 0; routerId <= Mle::kMaxRouterId; routerId++)
-#endif
-    {
-        if (IsAllocated(routerId) || mRouterIdReuseDelay[routerId] > 0)
-        {
-            continue;
-        }
-
-        if (freeBit == 0)
-        {
-            rval = Allocate(routerId);
-            OT_ASSERT(rval != nullptr);
-            ExitNow();
-        }
-
-        freeBit--;
-    }
+    router = Allocate(selectedRouterId);
+    OT_ASSERT(router != nullptr);
 
 exit:
-    return rval;
+    return router;
 }
 
 Router *RouterTable::Allocate(uint8_t aRouterId)