Pastebin
API
tools
faq
paste
Login
Sign up
Please fix the following errors:
New Paste
Syntax Highlighting
//HERE T.C. IS O(N^2) and space is O(N) which makes it best solution for JUMP DP variations. /* HAHHAHAHHAHHAHHHAHAHHAH I was able to solve it with a new code, which runs in T.C. O(N^2) but space is OPTIMISED to O(N). It beats 100% of the users in run time and ran in 0ms. I think this happened because of 3 reasons: 1) Large impact because it causes more sub problems to overlap and hence less recursive calls 2) Large Impact because it helps us skip invalid states unlike blind recursion, this is indeed smart recursion 3)Small impact because the size of memo table reduced, so easier to manage through recursive state */ class Solution { public: //CALL ONLY TO ALL THE VALID LEVELS FROM CURRENT LEVEL //VALID IS where you will have all the options available/they are all valid without needing to use a CONDITIONAL to check if the options are valid or not at the current level //when both the options are valid and available, we choose the option that is the BEST among them, as in this question, why would you NOT ROB a bank, when you CAN ROB the bank WITHOUT any hesitation and still avoid VIOLATING the property(ADJACENCY) stated in the question. //WHAT IS DIFFERENT?? /* ***********VERY VERY IMPORTANT: Previously we FORM ALL the possible VALID combinations to rob and keeping in mind to not violate the property of adjacency and then choose the best combination, but we were doing blind recursion, doing (level + 1) at every level after exploring ALL the valid options at that level with the help of a CONDITIONAL (conditional tells you when to explore a particular option to avoid generating any INVALID sequences/ OR sequences/subsets/subsequences that violates the property) and a CONDITIONAL requires something to be TRACKED while performing recursion, so that CONDITIONAL is always updated and in sync with the subset/subsequences being formed. such as, if we are at level, we update lastHouseRobbedIdx = 1, when we rob a house, but if we don't rob, then we simply make lastHouseRobbedIdx = 0 before moving to the next level(level + 1), telling that we didn't rob the last house at the next level(level + 1), which helps us make decision at level + 1, if we can explore the option rob at this level. BUT NOW we don't need to USE A CONDITIONAL TO CHECK WHETHER SOME OPTION IS VALID OR NOT AT SOME LEVEL, because instead of using conditional and only explore VALID options, we SIMPLY MOVE from a LEVEL, TO ALL THE POSSIBLE LEVELS called as VALID levels, WHERE ALL THE OPTIONS ARE VALID, here rob or not rob. AND as all the options are valid, we simply explore that SINGULAR OPTION that helps us make the BEST ANSWER. HERE ROBBING A BANK gives me money, and NOT ROBBING, gives me nothing. SO WE ROB at every VALID levels, without hesitation, because we ONLY EXPLORE VALID LEVELS, so robbing can be explored in any of these. ROBBING BEING THE BEST OPTION(maximises the answer), we ONLY ROB. THERE IS NO NEED TO EXPLICITLY call the 'DON'T ROB' option because it is not optimal. JUST ASK YOURSELF, IF THERE WAS NO PROPERTY ON ADJACENCY, we would have ROBBED at EVERY LEVEL/EVERY HOUSE. SO IS THIS, ONCE WE ROB A HOUSE AT A LEVEL, we MOVE TO THE NEXT LEVEL DIRECTLY WHERE ROBBING IS POSSIBLE AGAIN, SKIPPING ALL THE OPTIONS IN BETWEEN WHERE WE CAN'T ROB. SO WHY WON'T YOU ROB. AND WE EXPLORE ALL THE VALID LEVELS FROM A LEVEL, WHERE ROBBING IS POSSIBLE AGAIN, WITH THE HELP OF A LOOP(in subsequence type question, where order can't be changed) OR BINARY SEARCH (to move to the nearest/JUST next VALID LEVEL, in subset, where order can be changed with the help of SORTING). AS WE ARE FORMING ALL THE POSSIBLE combinations EXCLUDING the combinations which have INVALID LEVELS in them(it is just that we EXPLORE all the COMBINATIONS FORMED BY VALID LEVELS). *****BASICALLY THE LEVELS EXPLORED ARE THE LEVELS WHERE THE ADJACENCY CONDITION DOES NOT EXIST. SO WE ONLY CHOOSE THE BEST OPTION AT EVERY LEVEL and STILL NOT VIOLATE THE PROPERTY. (ADJACENCY CONDITION DOES NOT FAIL while doing this, because WE ONLY MOVE TO A LEVEL that is VALID, where CHOOSING THE BEST OPTION ONLY(robbing) DOES NOT VIOLATE THE PROPERTY). ONLY MOVING TO VALID LEVELS HAPPENS WITH THE HELP OF A LOOP OR BINARY SEARCH, WHERE WE PRE CHECK THAT IS IT A VALID LEVEL TO MOVE TO, RELATIVE TO THE CURRENT LEVEL(important), if it is THEN ONLY MOVE TO THAT LEVEL. RELATIVE TO CURRENT LEVEL IS: 1) HOUSE ROBBER: if current level is robbed, valid levels are in range[level + 2, n - 1], invalid is {level + 1}, as robbing at (level + 1) will violate property of adjacency. 2) HOUSE ROBBER 2: if current level is robbed, for current level in range[1, n - 1], VALID LEVELS are in range[level + 2, n - 1], INVALID LEVEL {level + 1} for current level = 0, VALID LEVELS are in range[level + 2, n - 2], INVALID LEVELS {level + 1(1), n - 1} where [] means an INCLUSIVE RANGE(boundaries included) and {} means a set of elements. IMPORTANT: RELATIVE TO level = 0, (level + 1)/1 is an invalid level to explore to as it VIOLATES ADJACENCY PROPERTY, AND (n - 1) is an INVALID LEVEL to explore to, because the ARRAY IS CIRCULAR, and because of that house 0 and house (n - 1) are neighbours/adjacent. So if the current level = 0, we run a loop from [level + 2, n - 2] to avoid exploring the invalids. WE MOVE TO THE LEVELS, WHERE ROBBING IS POSSIBLE NO MATTER WHAT CHOICES WE MAKE/OPTIONS WE EXPLORE, PROPERTY NEVER GETS VIOLATED, SO WE ONLY EXPLORE THE BEST OPTIONS OUT OF ALL OPTIONS as WE ARE FREE TO MAKE EVERY CHOICE.SO WHY CHOOSE A SUBOPTIMAL CHOICE, ONLY CHOOSE BEST */ /* ******* IMPORTANT In this question we need to have a separate variable zeroPicked that needs to be tracked in recursion For question like this, if done by this method, we don't have the memory of what was picked before in some previous level IMPLICITLY, and we are not actively tracking lastIdx EXPLICITLY. We move to ALL the next VALID levels RELATIVE to what was VALID ACCORDING TO THE LAST LEVEL. For cases like these where [200,3,140,20,10], imagine if 200 was picked, then the valid levels would be {140, 20}. So we can move to any of these levels as they are all valids with the help of the LOOP. Suppose we are currently exploring to 140. At 140, we pick it, making the sum = 340. The valid levels RELATIVE to 140 are {10}. So we explore 10, move to 10, pick 10,making sum = 350. THIS IS WROOOOOOONNNGGGGGG. As 10 is valid RELATIVE TO 140, but as we don't have the memory of what all elements have been included already, we can't check what all elements were also included prior to 140. In this case we picked 200 also before 140, which makes 10 INVALID RELATIVE to 200 as they are neighbours in circular array. But on the level of 140, we can't remember if 0th house(200) was included or not. So we EXPLICITLY NEED TO TRACK if 0th element was included or not, hence the variable zeroPicked. BUT as it is about inclusion/exclusion of a single element, it has only 2 states {0 or 1} / {included or not}. AS the PARAMETER zeroPicked is CHANGING throughout recursion, INFLUENCING (either decision making in base case OR helping write conditional/transition logic) here it helps us write CONDITIONAL NOT DERIVABLE from any other parameters THUS zeroPicked should be a part of memo key, just like level. */ int getMaxMoney(int level, int zeroPicked, vector<int> &nums, vector<vector<int> > &memo){ //base case if(level >= nums.size()){ return 0; } if(memo[level][zeroPicked] != -1){ return memo[level][zeroPicked]; } int n = nums.size(); //levels = house //options = ROB (we will always ROB at EACH LEVEL WE GO TO, because ROBBING IS ALWAYS VALID AT EVERY LEVEL(just because we only go to valid levels/ A level where all options are valid to explore to)AND THE BEST OPTION IS TO ROB AT EVERY HOUSE, IF IT IS POSSIBLE. int maxMoney = 0; //Very Important tracks if the loop at the current level ran or not bool flag = false; //level + 1 is invalid because of the property of adjacency. int nextValidLevelsStart = level + 2; //if level = 0, valid levels are upto and including (n - 2). (n - 1) is invalid level as the array is circular, and 0th and (n - 1)th element are adjacent. //For level != 0, valid levels are upto and including(n - 1) int nextValidLevelsEnd = level == 0 ? n - 2 : n - 1; //******IMPORTANT OBSERVATION(specific to this question only)/ GOOD ONE/ I OBSERVED IT MYSELF haha //if 0th house picked/robbed, (n - 1)th house cannot be picked/robbed //so update the nextValidLevelsEnd for all levels, where level != 0 //Now in all the paths where 0th house was robbed, for levels other than 0, there valid range cannot include the last house (n - 1) as the array is circular. if(zeroPicked){ nextValidLevelsEnd = n - 2; } //Move to all the valid levels with the help of LOOP. Binary Search can't be used, as array can't be sorted, as ORDER here has meaning just like in LIS. for(int i = nextValidLevelsStart; i <= nextValidLevelsEnd; i++){ flag = true; //We ONLY EXPLORE THE OPTION TO ROB at every level,as we ARE ALWAYS ON A VALID LEVEL, and Robbing is best option to explore out all the the other option. maxMoney = max(maxMoney, nums[level] + getMaxMoney(i, level == 0 ? 1 : zeroPicked, nums, memo)); } //********VERY IMPORTANT IMPLEMENTATION PRACTICE for DP WITH JUMPS VARIATION //if flag true, loop ran atleast once, and the money at house[level] was correctly included in the maxmoney //but if flag false, loop didn't even run once, and the money at house[level] was not included in the maxMoney (as this happens after we return from the recursive call INSIDE THE LOOP). But the house[level] is a VALID LEVEL, that's why we were able to reach this level and hence we have to INCLUDE the money of house[level] in the maxMoney, as we ALWAYS ROB A VALID LEVEL. The LOOP (not only helps make recursive call to ALL valid levels but it also HELPS to CORRECTLY INCLUDE THE money of the CURRENT LEVEL), IT DIDN'T RUN EVEN ONCE, and because of that, we have to EXPLICITLY ADD THE MONEY of house[level] to maxMoney. //So make it a general implementation practice in JUMP DPs, to track a flag inside a LEVEL to check whether the loop ran or not. If not ran/flag = false, EXPLICITLY ADD THE VALUE OF CURRENT LEVEL TO VARIABLES BEING RETURNED FROM LEVEL (here maxMoney); //******IMPORTANT // As loop didn't run once, meaning there are no valid levels to call from the current level // But the current level is a valid level and it's value must be returned. //Just because house[level] is VALID and can be robbed but no further houses exist that can be robbed. //maxMoney we can make here at this level will be nums[level] + recurse(level + 2, n - 1) //But no loop ran/no valid levels further to recurse, maxMoney = nums[level] // As the loop didn't run, no point of maxMoney, and it will be 0 for sure, because loop didn't run. //****IMPORTANT So the condition could have also looked like return flag == true ? maxMoney : nums[level]; return memo[level][zeroPicked] = flag == true ? maxMoney : maxMoney + nums[level]; } int rob(vector<int>& nums) { int maxMoney = 0; //memo key = memo(level, zeroPicked) => memo(n, 2) => 2*n = O(n) space vector<vector<int> > memo(nums.size(), vector<int>(2, -1)); for(int i = 0; i < nums.size(); i++){ //As the FIRST HOUSE in the subsequence(FIRST in the subsequence of ROBBED HOUSES, not the FIRST in the ORIGINAL NUMS ARRAY) is ALWAYS A VALID LEVEL(no previous houses, no property violation possible) //ALWAYS ROB AT THE FIRST HOUSE IN THE SUBSEQUENCE, JUST LIKE AS WE WILL ROB AT EVERY HOUSE IN THE SUBSEQUENCE, BECAUSE OUR SUBSEQUENCE IS FORMED ONLY OF VALID LEVELS.FIRST HOUSE and so as the other houses reached during recursion, are all valid, recursion treats it as VALID, as recursion was able to reach that level, and we can only reach levels that are valid, otherwise we won't have reached that level. //USING LOOP GUARANTEES THAT WE GIVE EVERY HOUSE THE CHANCE TO BE ROBBED FIRST IN THE SUBSEQUENCE. //IF WE START FROM HOUSE 0, instead of LOOPING, as we do in general INDEX BASED RECURSION, will generate answers/subsequences of houses robbed, where HOUSE 0 is always a part of subsequence/HOUSE 0 will always be ROBBED(as we call recursion on level 0, and it will be treated as a valid level and we always rob on a valid level). AND THIS IS NOT CORRECT. OPTIMAL ANSWER to the problem might or might not include HOUSE 0. SO GIVE EVERY HOUSE THE CHANCE TO BE THE FIRST in THE SUBSEQUENCE. maxMoney = max(maxMoney, getMaxMoney(i, 0, nums, memo)); } return maxMoney; } };
Optional Paste Settings
Category:
None
Cryptocurrency
Cybersecurity
Fixit
Food
Gaming
Haiku
Help
History
Housing
Jokes
Legal
Money
Movies
Music
Pets
Photo
Science
Software
Source Code
Spirit
Sports
Travel
TV
Writing
Tags:
Syntax Highlighting:
None
Bash
C
C#
C++
CSS
HTML
JSON
Java
JavaScript
Lua
Markdown (PRO members only)
Objective C
PHP
Perl
Python
Ruby
Swift
4CS
6502 ACME Cross Assembler
6502 Kick Assembler
6502 TASM/64TASS
ABAP
AIMMS
ALGOL 68
APT Sources
ARM
ASM (NASM)
ASP
ActionScript
ActionScript 3
Ada
Apache Log
AppleScript
Arduino
Asymptote
AutoIt
Autohotkey
Avisynth
Awk
BASCOM AVR
BNF
BOO
Bash
Basic4GL
Batch
BibTeX
Blitz Basic
Blitz3D
BlitzMax
BrainFuck
C
C (WinAPI)
C Intermediate Language
C for Macs
C#
C++
C++ (WinAPI)
C++ (with Qt extensions)
C: Loadrunner
CAD DCL
CAD Lisp
CFDG
CMake
COBOL
CSS
Ceylon
ChaiScript
Chapel
Clojure
Clone C
Clone C++
CoffeeScript
ColdFusion
Cuesheet
D
DCL
DCPU-16
DCS
DIV
DOT
Dart
Delphi
Delphi Prism (Oxygene)
Diff
E
ECMAScript
EPC
Easytrieve
Eiffel
Email
Erlang
Euphoria
F#
FO Language
Falcon
Filemaker
Formula One
Fortran
FreeBasic
FreeSWITCH
GAMBAS
GDB
GDScript
Game Maker
Genero
Genie
GetText
Go
Godot GLSL
Groovy
GwBasic
HQ9 Plus
HTML
HTML 5
Haskell
Haxe
HicEst
IDL
INI file
INTERCAL
IO
ISPF Panel Definition
Icon
Inno Script
J
JCL
JSON
Java
Java 5
JavaScript
Julia
KSP (Kontakt Script)
KiXtart
Kotlin
LDIF
LLVM
LOL Code
LScript
Latex
Liberty BASIC
Linden Scripting
Lisp
Loco Basic
Logtalk
Lotus Formulas
Lotus Script
Lua
M68000 Assembler
MIX Assembler
MK-61/52
MPASM
MXML
MagikSF
Make
MapBasic
Markdown (PRO members only)
MatLab
Mercury
MetaPost
Modula 2
Modula 3
Motorola 68000 HiSoft Dev
MySQL
Nagios
NetRexx
Nginx
Nim
NullSoft Installer
OCaml
OCaml Brief
Oberon 2
Objeck Programming Langua
Objective C
Octave
Open Object Rexx
OpenBSD PACKET FILTER
OpenGL Shading
Openoffice BASIC
Oracle 11
Oracle 8
Oz
PARI/GP
PCRE
PHP
PHP Brief
PL/I
PL/SQL
POV-Ray
ParaSail
Pascal
Pawn
Per
Perl
Perl 6
Phix
Pic 16
Pike
Pixel Bender
PostScript
PostgreSQL
PowerBuilder
PowerShell
ProFTPd
Progress
Prolog
Properties
ProvideX
Puppet
PureBasic
PyCon
Python
Python for S60
QBasic
QML
R
RBScript
REBOL
REG
RPM Spec
Racket
Rails
Rexx
Robots
Roff Manpage
Ruby
Ruby Gnuplot
Rust
SAS
SCL
SPARK
SPARQL
SQF
SQL
SSH Config
Scala
Scheme
Scilab
SdlBasic
Smalltalk
Smarty
StandardML
StoneScript
SuperCollider
Swift
SystemVerilog
T-SQL
TCL
TeXgraph
Tera Term
TypeScript
TypoScript
UPC
Unicon
UnrealScript
Urbi
VB.NET
VBScript
VHDL
VIM
Vala
Vedit
VeriLog
Visual Pro Log
VisualBasic
VisualFoxPro
WHOIS
WhiteSpace
Winbatch
XBasic
XML
XPP
Xojo
Xorg Config
YAML
YARA
Z80 Assembler
ZXBasic
autoconf
jQuery
mIRC
newLISP
q/kdb+
thinBasic
Paste Expiration:
Never
Burn after read
10 Minutes
1 Hour
1 Day
1 Week
2 Weeks
1 Month
6 Months
1 Year
Paste Exposure:
Public
Unlisted
Private
Folder:
(members only)
Password
NEW
Enabled
Disabled
Burn after read
NEW
Paste Name / Title:
Create New Paste
Hello
Guest
Sign Up
or
Login
Sign in with Facebook
Sign in with Twitter
Sign in with Google
You are currently not logged in, this means you can not edit or delete anything you paste.
Sign Up
or
Login
Public Pastes
Untitled
6 hours ago | 1.88 KB
Untitled
6 hours ago | 0.67 KB
Untitled
6 hours ago | 3.33 KB
Untitled
7 hours ago | 1.00 KB
Untitled
7 hours ago | 0.33 KB
Untitled
7 hours ago | 1.55 KB
my software
10 hours ago | 0.03 KB
disable countdown timer in cart for drop pric...
PHP | 15 hours ago | 0.23 KB
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the
Cookies Policy
.
OK, I Understand
Not a member of Pastebin yet?
Sign Up
, it unlocks many cool features!