384. Shuffle an Array && 382. Linked List Random Node

384. Shuffle an Array

Shuffle a set of numbers without duplicates.

Example:

// Init an array with set 1, 2, and 3.
int[] nums = {1,2,3};
Solution solution = new Solution(nums);
// Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned.
solution.shuffle();
// Resets the array back to its original configuration [1,2,3].
solution.reset();
// Returns the random shuffling of array [1,2,3].
solution.shuffle();

Solution: think about how you shuffle a deck of cards. You pick a card, and use it as the first/last card, then pick a second one, use it as a second/second last one.......

public class Solution {

  private int[] orig = null;
  private int[] current = null;
  private Random random = new Random();

  public Solution(int[] nums) {
    this.orig = nums;
    this.current = nums.clone();
  }

  /**
   * Resets the array to its original configuration and return it.
   */
  public int[] reset() {
    return orig;
  }

  /**
   * Returns a random shuffling of the array.
   */
  public int[] shuffle() {
    for (int i = 0; i < current.length; ++i) {
      int pick = random.nextInt(current.length);
      int swap = current.length - 1 - i;
      int temp = current[swap];
      current[swap] = current[pick];
      current[pick] = temp;
    }
    return current;
  }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(nums);
 * int[] param_1 = obj.reset();
 * int[] param_2 = obj.shuffle();
 */

 

382. 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.

Follow up:
What if the linked list is extremely large and its length is unknown to you? Could you solve this efficiently without using extra space?

Example:

// Init a singly linked list [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() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
solution.getRandom();

 Reservoir Sampling

 

Probablity table of choosing a node after each iteration

number of iterations Node1 Node2 Node3 Node4
1st iteration 1      
2nd iteration 1/2 1/2    
3rd iteration 2/3 2/3 1/3  
4th iteration 3/4 3/4 3/4 1/4
total 1*1/2*2/3*3/4=1/4 1/2*2/3*3/4=1/4 1/3*3/4=1/4 1/4

 

 

 

 

 

 

 

 

 

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {

    private ListNode head = null;
    private Random rand = new Random();

    /** @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) {
        this.head = head;
    }
    
    /** Returns a random node's value. */
    public int getRandom() {
        ListNode result = null;
        ListNode current = head;
    
        for (int i = 1; current != null; ++i) {
          if (rand.nextInt(i) == 0) {
            result = current;
          }
          current = current.next;
        }
    
        return result.val;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(head);
 * int param_1 = obj.getRandom();
 */

 

 

posted @ 2016-08-12 10:03  新一代的天皇巨星  阅读(734)  评论(0)    收藏  举报