DEV Community

DevCorner
DevCorner

Posted on

This Java program generates all possible subsets (the power set) of a given array using backtracking

Reference Youtube video:Link
This Java program generates all possible subsets (the power set) of a given array using backtracking. Let's break it down step by step.


Let given array be [1, 2, 3].

Understanding the Code

The program consists of two main functions:

  1. subsets(int[] nums):

    • Initializes the result list (list) to store all subsets.
    • Sorts the input array (though sorting is unnecessary in this case).
    • Calls the helper function backtrack() to generate subsets.
  2. backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start):

    • Adds the current subset (tempList) to the result list (list).
    • Iterates through the numbers in nums, adding one element at a time to tempList, and recursively explores further subsets.
    • After recursion, removes the last element to backtrack and explore other possibilities.

Step-by-Step Execution

Let's assume the input is:

nums = [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Step 1: Start Execution

  • subsets(nums) is called with nums = [1, 2, 3]
  • list is initialized as an empty list: list = []
  • backtrack() is called with:
  backtrack(list, tempList = [], nums = [1, 2, 3], start = 0)
Enter fullscreen mode Exit fullscreen mode

Step 2: First Call to backtrack

  • tempList = [] is added to list
  • list = [[]]
  • For Loop Iteration 1 (i = 0):
    • Add 1 to tempList → tempList = [1]
    • Call backtrack(list, tempList = [1], nums, start = 1)

Step 3: Second Call to backtrack

  • tempList = [1] is added to list
  • list = [[], [1]]
  • For Loop Iteration 1 (i = 1):
    • Add 2 to tempList → tempList = [1, 2]
    • Call backtrack(list, tempList = [1, 2], nums, start = 2)

Step 4: Third Call to backtrack

  • tempList = [1, 2] is added to list
  • list = [[], [1], [1, 2]]
  • For Loop Iteration 1 (i = 2):
    • Add 3 to tempList → tempList = [1, 2, 3]
    • Call backtrack(list, tempList = [1, 2, 3], nums, start = 3)

Step 5: Fourth Call to backtrack

  • tempList = [1, 2, 3] is added to list
  • list = [[], [1], [1, 2], [1, 2, 3]]
  • start = 3 (out of bounds), so the function returns
  • Backtrack: Remove 3tempList = [1, 2]

Step 6: Backtrack to Third Call

  • Continue loop in Third Call (i = 2 finished)
  • Backtrack: Remove 2tempList = [1]
  • For Loop Iteration 2 (i = 2):
    • Add 3 to tempList → tempList = [1, 3]
    • Call backtrack(list, tempList = [1, 3], nums, start = 3)

Step 7: Fifth Call to backtrack

  • tempList = [1, 3] is added to list
  • list = [[], [1], [1, 2], [1, 2, 3], [1, 3]]
  • Backtrack: Remove 3tempList = [1]
  • Backtrack: Remove 1tempList = []

Step 8: Backtrack to Second Call

  • For Loop Iteration 2 (i = 1):
    • Add 2 to tempList → tempList = [2]
    • Call backtrack(list, tempList = [2], nums, start = 2)

Step 9: Sixth Call to backtrack

  • tempList = [2] is added to list
  • list = [[], [1], [1, 2], [1, 2, 3], [1, 3], [2]]
  • For Loop Iteration 1 (i = 2):
    • Add 3 to tempList → tempList = [2, 3]
    • Call backtrack(list, tempList = [2, 3], nums, start = 3)

Step 10: Seventh Call to backtrack

  • tempList = [2, 3] is added to list
  • list = [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3]]
  • Backtrack: Remove 3tempList = [2]
  • Backtrack: Remove 2tempList = []

Step 11: Backtrack to First Call

  • For Loop Iteration 3 (i = 2):
    • Add 3 to tempList → tempList = [3]
    • Call backtrack(list, tempList = [3], nums, start = 3)

Step 12: Eighth Call to backtrack

  • tempList = [3] is added to list
  • list = [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
  • Backtrack: Remove 3tempList = []
  • All iterations complete. Return list.

Final Output

[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  1. Backtracking Approach:

    • We explore subsets recursively, adding and removing elements (backtracking).
    • The tempList is used to build subsets, and each state is stored in list.
  2. Time Complexity:

    • O(2^n) → Since each element can either be included or not, we generate 2^n subsets.
  3. Space Complexity:

    • O(2^n * n) → Each subset requires space, and there are 2^n subsets, each taking up to O(n) space.
  4. Recursive Tree Visualization:

    • The recursive function creates a tree where each level corresponds to choosing or skipping an element.

This step-by-step breakdown explains how subsets are generated recursively using backtracking. 🚀

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay