First, we check if the length of the array \(\textit{nums}\) is divisible by \(\textit{k}\). If it is not divisible, it means the array cannot be divided into subarrays of length \(\textit{k}\), and we return \(\text{false}\) directly.
Next, we use a hash table \(\textit{cnt}\) to count the occurrences of each number in the array \(\textit{nums}\), and then we sort the array \(\textit{nums}\).
After sorting, we iterate through the array \(\textit{nums}\), and for each number \(x\), if \(\textit{cnt}[x]\) is not \(0\), we enumerate each number \(y\) from \(x\) to \(x + \textit{k} - 1\). If \(\textit{cnt}[y]\) is \(0\), it means we cannot divide the array into subarrays of length \(\textit{k}\), and we return \(\text{false}\) directly. Otherwise, we decrement \(\textit{cnt}[y]\) by \(1\).
After the loop, if no issues were encountered, it means we can divide the array into subarrays of length \(\textit{k}\), and we return \(\text{true}\).
The time complexity is \(O(n \times \log n)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array \(\textit{nums}\).
Similar to Solution 1, we first check if the length of the array \(\textit{nums}\) is divisible by \(\textit{k}\). If it is not divisible, it means the array cannot be divided into subarrays of length \(\textit{k}\), and we return \(\text{false}\) directly.
Next, we use an ordered set \(\textit{sd}\) to count the occurrences of each number in the array \(\textit{nums}\).
Then, we repeatedly extract the smallest value \(x\) from the ordered set and enumerate each number \(y\) from \(x\) to \(x + \textit{k} - 1\). If these numbers all appear in the ordered set with non-zero occurrences, we decrement their occurrence count by \(1\). If the occurrence count becomes \(0\) after the decrement, we remove the number from the ordered set; otherwise, it means we cannot divide the array into subarrays of length \(\textit{k}\), and we return \(\text{false}\).
If we can successfully divide the array into subarrays of length \(\textit{k}\), we return \(\text{true}\) after completing the traversal.
The time complexity is \(O(n \times \log n)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array \(\textit{nums}\).
functionisPossibleDivide(nums:number[],k:number):boolean{if(nums.length%k!==0){returnfalse;}consttm=newTreeMap<number,number>();for(constxofnums){tm.set(x,(tm.get(x)||0)+1);}while(tm.size()){constx=tm.first()![0];for(lety=x;y<x+k;++y){if(!tm.has(y)){returnfalse;}if(tm.get(y)!===1){tm.delete(y);}else{tm.set(y,tm.get(y)!-1);}}}returntrue;}typeCompare<T>=(lhs:T,rhs:T)=>number;classRBTreeNode<T=number>{data:T;count:number;left:RBTreeNode<T>|null;right:RBTreeNode<T>|null;parent:RBTreeNode<T>|null;color:number;constructor(data:T){this.data=data;this.left=this.right=this.parent=null;this.color=0;this.count=1;}sibling():RBTreeNode<T>|null{if(!this.parent)returnnull;// sibling null if no parentreturnthis.isOnLeft()?this.parent.right:this.parent.left;}isOnLeft():boolean{returnthis===this.parent!.left;}hasRedChild():boolean{return(Boolean(this.left&&this.left.color===0)||Boolean(this.right&&this.right.color===0));}}classRBTree<T>{root:RBTreeNode<T>|null;lt:(l:T,r:T)=>boolean;constructor(compare:Compare<T>=(l:T,r:T)=>(l<r?-1:l>r?1:0)){this.root=null;this.lt=(l:T,r:T)=>compare(l,r)<0;}rotateLeft(pt:RBTreeNode<T>):void{constright=pt.right!;pt.right=right.left;if(pt.right)pt.right.parent=pt;right.parent=pt.parent;if(!pt.parent)this.root=right;elseif(pt===pt.parent.left)pt.parent.left=right;elsept.parent.right=right;right.left=pt;pt.parent=right;}rotateRight(pt:RBTreeNode<T>):void{constleft=pt.left!;pt.left=left.right;if(pt.left)pt.left.parent=pt;left.parent=pt.parent;if(!pt.parent)this.root=left;elseif(pt===pt.parent.left)pt.parent.left=left;elsept.parent.right=left;left.right=pt;pt.parent=left;}swapColor(p1:RBTreeNode<T>,p2:RBTreeNode<T>):void{consttmp=p1.color;p1.color=p2.color;p2.color=tmp;}swapData(p1:RBTreeNode<T>,p2:RBTreeNode<T>):void{consttmp=p1.data;p1.data=p2.data;p2.data=tmp;}fixAfterInsert(pt:RBTreeNode<T>):void{letparent=null;letgrandParent=null;while(pt!==this.root&&pt.color!==1&&pt.parent?.color===0){parent=pt.parent;grandParent=pt.parent.parent;/* Case : A Parent of pt is left child of Grand-parent of pt */if(parent===grandParent?.left){constuncle=grandParent.right;/* Case : 1 The uncle of pt is also red Only Recoloring required */if(uncle&&uncle.color===0){grandParent.color=0;parent.color=1;uncle.color=1;pt=grandParent;}else{/* Case : 2 pt is right child of its parent Left-rotation required */if(pt===parent.right){this.rotateLeft(parent);pt=parent;parent=pt.parent;}/* Case : 3 pt is left child of its parent Right-rotation required */this.rotateRight(grandParent);this.swapColor(parent!,grandParent);pt=parent!;}}else{/* Case : B Parent of pt is right child of Grand-parent of pt */constuncle=grandParent!.left;/* Case : 1 The uncle of pt is also red Only Recoloring required */if(uncle!=null&&uncle.color===0){grandParent!.color=0;parent.color=1;uncle.color=1;pt=grandParent!;}else{/* Case : 2 pt is left child of its parent Right-rotation required */if(pt===parent.left){this.rotateRight(parent);pt=parent;parent=pt.parent;}/* Case : 3 pt is right child of its parent Left-rotation required */this.rotateLeft(grandParent!);this.swapColor(parent!,grandParent!);pt=parent!;}}}this.root!.color=1;}delete(val:T):boolean{constnode=this.find(val);if(!node)returnfalse;node.count--;if(!node.count)this.deleteNode(node);returntrue;}deleteAll(val:T):boolean{constnode=this.find(val);if(!node)returnfalse;this.deleteNode(node);returntrue;}deleteNode(v:RBTreeNode<T>):void{constu=BSTreplace(v);// True when u and v are both blackconstuvBlack=(u===null||u.color===1)&&v.color===1;constparent=v.parent!;if(!u){// u is null therefore v is leafif(v===this.root)this.root=null;// v is root, making root nullelse{if(uvBlack){// u and v both black// v is leaf, fix double black at vthis.fixDoubleBlack(v);}else{// u or v is redif(v.sibling()){// sibling is not null, make it red"v.sibling()!.color=0;}}// delete v from the treeif(v.isOnLeft())parent.left=null;elseparent.right=null;}return;}if(!v.left||!v.right){// v has 1 childif(v===this.root){// v is root, assign the value of u to v, and delete uv.data=u.data;v.left=v.right=null;}else{// Detach v from tree and move u upif(v.isOnLeft())parent.left=u;elseparent.right=u;u.parent=parent;if(uvBlack)this.fixDoubleBlack(u);// u and v both black, fix double black at uelseu.color=1;// u or v red, color u black}return;}// v has 2 children, swap data with successor and recursethis.swapData(u,v);this.deleteNode(u);// find node that replaces a deleted node in BSTfunctionBSTreplace(x:RBTreeNode<T>):RBTreeNode<T>|null{// when node have 2 childrenif(x.left&&x.right)returnsuccessor(x.right);// when leafif(!x.left&&!x.right)returnnull;// when single childreturnx.left??x.right;}// find node that do not have a left child// in the subtree of the given nodefunctionsuccessor(x:RBTreeNode<T>):RBTreeNode<T>{lettemp=x;while(temp.left)temp=temp.left;returntemp;}}fixDoubleBlack(x:RBTreeNode<T>):void{if(x===this.root)return;// Reached rootconstsibling=x.sibling();constparent=x.parent!;if(!sibling){// No sibiling, double black pushed upthis.fixDoubleBlack(parent);}else{if(sibling.color===0){// Sibling redparent.color=0;sibling.color=1;if(sibling.isOnLeft())this.rotateRight(parent);// left caseelsethis.rotateLeft(parent);// right casethis.fixDoubleBlack(x);}else{// Sibling blackif(sibling.hasRedChild()){// at least 1 red childrenif(sibling.left&&sibling.left.color===0){if(sibling.isOnLeft()){// left leftsibling.left.color=sibling.color;sibling.color=parent.color;this.rotateRight(parent);}else{// right leftsibling.left.color=parent.color;this.rotateRight(sibling);this.rotateLeft(parent);}}else{if(sibling.isOnLeft()){// left rightsibling.right!.color=parent.color;this.rotateLeft(sibling);this.rotateRight(parent);}else{// right rightsibling.right!.color=sibling.color;sibling.color=parent.color;this.rotateLeft(parent);}}parent.color=1;}else{// 2 black childrensibling.color=0;if(parent.color===1)this.fixDoubleBlack(parent);elseparent.color=1;}}}}insert(data:T):boolean{// search for a position to insertletparent=this.root;while(parent){if(this.lt(data,parent.data)){if(!parent.left)break;elseparent=parent.left;}elseif(this.lt(parent.data,data)){if(!parent.right)break;elseparent=parent.right;}elsebreak;}// insert node into parentconstnode=newRBTreeNode(data);if(!parent)this.root=node;elseif(this.lt(node.data,parent.data))parent.left=node;elseif(this.lt(parent.data,node.data))parent.right=node;else{parent.count++;returnfalse;}node.parent=parent;this.fixAfterInsert(node);returntrue;}search(predicate:(val:T)=>boolean,direction:'left'|'right'):T|undefined{letp=this.root;letresult=null;while(p){if(predicate(p.data)){result=p;p=p[direction];}else{p=p[direction==='left'?'right':'left'];}}returnresult?.data;}find(data:T):RBTreeNode<T>|null{letp=this.root;while(p){if(this.lt(data,p.data)){p=p.left;}elseif(this.lt(p.data,data)){p=p.right;}elsebreak;}returnp??null;}count(data:T):number{constnode=this.find(data);returnnode?node.count:0;}*inOrder(root:RBTreeNode<T>=this.root!):Generator<T,undefined,void>{if(!root)return;for(constvofthis.inOrder(root.left!))yieldv;yieldroot.data;for(constvofthis.inOrder(root.right!))yieldv;}*reverseInOrder(root:RBTreeNode<T>=this.root!):Generator<T,undefined,void>{if(!root)return;for(constvofthis.reverseInOrder(root.right!))yieldv;yieldroot.data;for(constvofthis.reverseInOrder(root.left!))yieldv;}}classTreeMap<K=number,V=unknown>{_size:number;tree:RBTree<K>;map:Map<K,V>=newMap();compare:Compare<K>;constructor(collection:Array<[K,V]>|Compare<K>=[],compare:Compare<K>=(l:K,r:K)=>(l<r?-1:l>r?1:0),){if(typeofcollection==='function'){compare=collection;collection=[];}this._size=0;this.compare=compare;this.tree=newRBTree(compare);for(const[key,val]ofcollection)this.set(key,val);}size():number{returnthis._size;}has(key:K):boolean{return!!this.tree.find(key);}get(key:K):V|undefined{returnthis.map.get(key);}set(key:K,val:V):boolean{constsuccessful=this.tree.insert(key);this._size+=successful?1:0;this.map.set(key,val);returnsuccessful;}delete(key:K):boolean{constdeleted=this.tree.deleteAll(key);this._size-=deleted?1:0;returndeleted;}ceil(target:K):[K,V]|undefined{returnthis.toKeyValue(this.tree.search(key=>this.compare(key,target)>=0,'left'));}floor(target:K):[K,V]|undefined{returnthis.toKeyValue(this.tree.search(key=>this.compare(key,target)<=0,'right'));}higher(target:K):[K,V]|undefined{returnthis.toKeyValue(this.tree.search(key=>this.compare(key,target)>0,'left'));}lower(target:K):[K,V]|undefined{returnthis.toKeyValue(this.tree.search(key=>this.compare(key,target)<0,'right'));}first():[K,V]|undefined{returnthis.toKeyValue(this.tree.inOrder().next().value);}last():[K,V]|undefined{returnthis.toKeyValue(this.tree.reverseInOrder().next().value);}shift():[K,V]|undefined{constfirst=this.first();if(first===undefined)returnundefined;this.delete(first[0]);returnfirst;}pop():[K,V]|undefined{constlast=this.last();if(last===undefined)returnundefined;this.delete(last[0]);returnlast;}toKeyValue(key:K):[K,V];toKeyValue(key:undefined):undefined;toKeyValue(key:K|undefined):[K,V]|undefined;toKeyValue(key:K|undefined):[K,V]|undefined{returnkey!=null?[key,this.map.get(key)!]:undefined;}*[Symbol.iterator]():Generator<[K,V],void,void>{for(constkeyofthis.keys())yieldthis.toKeyValue(key);}*keys():Generator<K,void,void>{for(constkeyofthis.tree.inOrder())yieldkey;}*values():Generator<V,undefined,void>{for(constkeyofthis.keys())yieldthis.map.get(key)!;returnundefined;}*rkeys():Generator<K,undefined,void>{for(constkeyofthis.tree.reverseInOrder())yieldkey;returnundefined;}*rvalues():Generator<V,undefined,void>{for(constkeyofthis.rkeys())yieldthis.map.get(key)!;returnundefined;}}