<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ?LeetCode刷題實(shí)戰(zhàn)382:鏈表隨機(jī)節(jié)點(diǎn)

          共 3043字,需瀏覽 7分鐘

           ·

          2021-09-18 10:17

          算法的重要性,我就不多說(shuō)了吧,想去大廠,就必須要經(jīng)過(guò)基礎(chǔ)知識(shí)和業(yè)務(wù)邏輯面試+算法面試。所以,為了提高大家的算法能力,這個(gè)公眾號(hào)后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !

          今天和大家聊的問(wèn)題叫做 鏈表隨機(jī)節(jié)點(diǎn),我們先來(lái)看題面:
          https://leetcode-cn.com/problems/linked-list-random-node/


          Given a singly linked list, return a random node's value from the linked list. Each node must have the same probability of being chosen.

          Implement the Solution class:
          Solution(ListNode head) Initializes the object with the integer array nums.
          int getRandom() Chooses a node randomly from the list and returns its value. All the nodes of the list should be equally likely to be choosen.

          給定一個(gè)單鏈表,隨機(jī)選擇鏈表的一個(gè)節(jié)點(diǎn),并返回相應(yīng)的節(jié)點(diǎn)值。保證每個(gè)節(jié)點(diǎn)被選的概率一樣。
          進(jìn)階:
          如果鏈表十分大且長(zhǎng)度未知,如何解決這個(gè)問(wèn)題?你能否使用常數(shù)級(jí)空間復(fù)雜度實(shí)現(xiàn)?

          示例

          // 初始化一個(gè)單鏈表 [1,2,3].
          ListNode head = new ListNode(1);
          head.next = new ListNode(2);
          head.next.next = new ListNode(3);
          Solution solution = new Solution(head);
          // getRandom()方法應(yīng)隨機(jī)返回1,2,3中的一個(gè),保證每個(gè)元素被返回的概率相等。
          solution.getRandom();


          解題

          https://blog.csdn.net/Yubochang/article/details/109406986
          最簡(jiǎn)單的就是統(tǒng)計(jì)個(gè)數(shù),然后隨機(jī)返回一個(gè)值回去,但是這樣子就得兩次遍歷,第一次統(tǒng)計(jì)個(gè)數(shù),第二次獲得特定節(jié)點(diǎn)值,當(dāng)然你也可以第一次遍歷是把鏈表存在ArrayList里,然后直接get,但是這樣太浪費(fèi)內(nèi)存。

          另外的,就是采用蓄水池抽樣算法,即第 i 個(gè)節(jié)點(diǎn)被抽取當(dāng)作結(jié)果的概率為 1/i ,順序概率抽取、替換,這樣我們就不用去統(tǒng)計(jì)整體的n,也能保證被選中概率一樣。

          怎么保證?

          數(shù)學(xué)歸納法:

          第一個(gè)節(jié)點(diǎn)A,1/1的概率作為結(jié)果;

          第二個(gè)節(jié)點(diǎn)B,1/2的概率作為結(jié)果,那么此時(shí)A就有1/2的概率被替換,于是A=1*1/2=1/2的概率不被替換,作為結(jié)果;

          第三個(gè)節(jié)點(diǎn)C,1/3的概率作為結(jié)果,那么此時(shí)A=1/2*2/3=1/3,B=1/2*2/3=1/3概率不被替換,作為結(jié)果;

          ......

          第n個(gè)節(jié)點(diǎn),1/n的概率作為結(jié)果,那么此時(shí)A=1/(n-1)*(n-1)/n=1/n,B=...,C=...。

          神奇嗎?前面的節(jié)點(diǎn)的本身留下概率大,但是經(jīng)過(guò)篩選的次數(shù)多導(dǎo)致概率下降,所以每一次篩選每個(gè)節(jié)點(diǎn)被選中概率都是一樣的。


          import java.util.Random;
          class Solution {
           
              private ListNode ls;
           
              /** @param head The linked list's head.
                  Note that the head is guaranteed to be not null, so it contains at least one node. */

              public Solution(ListNode head) {
                  ls=head;
              }
              
              /** Returns a random node's value. */
              public int getRandom() {
                  ListNode tls=ls;
                  Random rd=new Random(); //隨機(jī)數(shù)隨便,保證概率為1/i即可
                  int i=1,rs=tls.val;
                  while(tls!=null){
                      if(rd.nextInt(i++)==0){
                          rs=tls.val;
                      }
                      tls=tls.next;
                  }
                  return rs;
              }
          }


          好了,今天的文章就到這里,如果覺(jué)得有所收獲,請(qǐng)順手點(diǎn)個(gè)在看或者轉(zhuǎn)發(fā)吧,你們的支持是我最大的動(dòng)力 。

          上期推文:

          LeetCode1-380題匯總,希望對(duì)你有點(diǎn)幫助!
          LeetCode刷題實(shí)戰(zhàn)381:O(1) 時(shí)間插入、刪除和獲取隨機(jī)元素 - 允許重復(fù)

          瀏覽 79
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91精品国产日韩91久久 | 国产精品在线观看成人视频 | 欧美美女日皮视频 | 97国产精品视频人人做人人爱 | 久久久久久中文字幕 |