template
js
js
// 常用的模版;
// listNode
class ListNode {
constructor(val, next) {
this.val = val;
this.next = next || null;
}
}
// console.log(new ListNode(1))
// TreeNode
class TreeNode {
constructor(val, leftChild, rightChild) {
this.val = val;
this.left = leftChild || null;
this.right = rightChild || null;
}
}
// console.log(new TreeNode(1))
// heap: 默认是小根堆,只用使用add, peek, size, poll,即可;
/**
* example1:
var x = new FastPriorityQueue();
x.add(1);
x.add(0);
x.add(5);
x.add(4);
x.add(3);
x.peek(); // should return 0, leaves x unchanged
x.size; // should return 5, leaves x unchanged
while(!x.isEmpty()) {
console.log(x.poll());
} // will print 0 1 3 4 5
x.trim(); // (optional) optimizes memory usage
example2:
var x = new FastPriorityQueue(function(a, b) {
return a > b;
});
x.add(1);
x.add(0);
x.add(5);
x.add(4);
x.add(3);
while (!x.isEmpty()) {
console.log(x.poll());
} // will print 5 4 3 1 0
*/
// the provided comparator function should take a, b and return *true* when a < b
function FastPriorityQueue(comparator) {
const defaultcomparator = function (a, b) {
return a < b;
};
if (!(this instanceof FastPriorityQueue)) return new FastPriorityQueue(comparator);
this.array = [];
this.size = 0;
this.compare = comparator || defaultcomparator;
}
// copy the priority queue into another, and return it. Queue items are shallow-copied.
// Runs in `O(n)` time.
FastPriorityQueue.prototype.clone = function () {
var fpq = new FastPriorityQueue(this.compare);
fpq.size = this.size;
fpq.array = this.array.slice(0, this.size);
return fpq;
};
// Add an element into the queue
// runs in O(log n) time
FastPriorityQueue.prototype.add = function (myval) {
var i = this.size;
this.array[this.size] = myval;
this.size += 1;
var p;
var ap;
while (i > 0) {
p = (i - 1) >> 1;
ap = this.array[p];
if (!this.compare(myval, ap)) {
break;
}
this.array[i] = ap;
i = p;
}
this.array[i] = myval;
};
// replace the content of the heap by provided array and "heapify it"
FastPriorityQueue.prototype.heapify = function (arr) {
this.array = arr;
this.size = arr.length;
var i;
for (i = this.size >> 1; i >= 0; i--) {
this._percolateDown(i);
}
};
// for internal use
FastPriorityQueue.prototype._percolateUp = function (i, force) {
var myval = this.array[i];
var p;
var ap;
while (i > 0) {
p = (i - 1) >> 1;
ap = this.array[p];
// force will skip the compare
if (!force && !this.compare(myval, ap)) {
break;
}
this.array[i] = ap;
i = p;
}
this.array[i] = myval;
};
// for internal use
FastPriorityQueue.prototype._percolateDown = function (i) {
var size = this.size;
var hsize = this.size >>> 1;
var ai = this.array[i];
var l;
var r;
var bestc;
while (i < hsize) {
l = (i << 1) + 1;
r = l + 1;
bestc = this.array[l];
if (r < size) {
if (this.compare(this.array[r], bestc)) {
l = r;
bestc = this.array[r];
}
}
if (!this.compare(bestc, ai)) {
break;
}
this.array[i] = bestc;
i = l;
}
this.array[i] = ai;
};
// internal
// _removeAt(index) will remove the item at the given index from the queue,
// retaining balance. returns the removed item, or undefined if nothing is removed.
FastPriorityQueue.prototype._removeAt = function (index) {
if (index > this.size - 1 || index < 0) return undefined;
// impl1:
//this.array.splice(index, 1);
//this.heapify(this.array);
// impl2:
this._percolateUp(index, true);
return this.poll();
};
// remove(myval) will remove an item matching the provided value from the
// queue, checked for equality by using the queue's comparator.
// return true if removed, false otherwise.
FastPriorityQueue.prototype.remove = function (myval) {
for (var i = 0; i < this.size; i++) {
if (!this.compare(this.array[i], myval) && !this.compare(myval, this.array[i])) {
// items match, comparator returns false both ways, remove item
this._removeAt(i);
return true;
}
}
return false;
};
// removeOne(callback) will execute the callback function for each item of the queue
// and will remove the first item for which the callback will return true.
// return the removed item, or undefined if nothing is removed.
FastPriorityQueue.prototype.removeOne = function (callback) {
if (typeof callback !== "function") {
return undefined;
}
for (var i = 0; i < this.size; i++) {
if (callback(this.array[i])) {
return this._removeAt(i);
}
}
};
// remove(callback[, limit]) will execute the callback function for each item of
// the queue and will remove each item for which the callback returns true, up to
// a max limit of removed items if specified or no limit if unspecified.
// return an array containing the removed items.
// The callback function should be a pure function.
FastPriorityQueue.prototype.removeMany = function (callback, limit) {
// Skip unnecessary processing for edge cases
if (typeof callback !== "function" || this.size < 1) {
return [];
}
limit = limit ? Math.min(limit, this.size) : this.size;
// Prepare the results container to hold up to the results limit
var resultSize = 0;
var result = new Array(limit);
// Prepare a temporary array to hold items we'll traverse through and need to keep
var tmpSize = 0;
var tmp = new Array(this.size);
while (resultSize < limit && !this.isEmpty()) {
// Dequeue items into either the results or our temporary array
var item = this.poll();
if (callback(item)) {
result[resultSize++] = item;
} else {
tmp[tmpSize++] = item;
}
}
// Update the result array with the exact number of results
result.length = resultSize;
// Re-add all the items we can keep
var i = 0;
while (i < tmpSize) {
this.add(tmp[i++]);
}
return result;
};
// Look at the top of the queue (one of the smallest elements) without removing it
// executes in constant time
//
// Calling peek on an empty priority queue returns
// the "undefined" value.
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/undefined
//
FastPriorityQueue.prototype.peek = function () {
if (this.size == 0) return undefined;
return this.array[0];
};
// remove the element on top of the heap (one of the smallest elements)
// runs in logarithmic time
//
// If the priority queue is empty, the function returns the
// "undefined" value.
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/undefined
//
// For long-running and large priority queues, or priority queues
// storing large objects, you may want to call the trim function
// at strategic times to recover allocated memory.
FastPriorityQueue.prototype.poll = function () {
if (this.size == 0) return undefined;
var ans = this.array[0];
if (this.size > 1) {
this.array[0] = this.array[--this.size];
this._percolateDown(0);
} else {
this.size -= 1;
}
return ans;
};
// This function adds the provided value to the heap, while removing
// and returning one of the smallest elements (like poll). The size of the queue
// thus remains unchanged.
FastPriorityQueue.prototype.replaceTop = function (myval) {
if (this.size == 0) return undefined;
var ans = this.array[0];
this.array[0] = myval;
this._percolateDown(0);
return ans;
};
// recover unused memory (for long-running priority queues)
FastPriorityQueue.prototype.trim = function () {
this.array = this.array.slice(0, this.size);
};
// Check whether the heap is empty
FastPriorityQueue.prototype.isEmpty = function () {
return this.size === 0;
};
// iterate over the items in order, pass a callback that receives (item, index) as args.
// TODO once we transpile, uncomment
// if (Symbol && Symbol.iterator) {
// FastPriorityQueue.prototype[Symbol.iterator] = function*() {
// if (this.isEmpty()) return;
// var fpq = this.clone();
// while (!fpq.isEmpty()) {
// yield fpq.poll();
// }
// };
// }
FastPriorityQueue.prototype.forEach = function (callback) {
if (this.isEmpty() || typeof callback != 'function') return;
var i = 0;
var fpq = this.clone();
while (!fpq.isEmpty()) {
callback(fpq.poll(), i++);
}
};
// return the k 'smallest' elements of the queue as an array,
// runs in O(k log k) time, the elements are not removed
// from the priority queue.
FastPriorityQueue.prototype.kSmallest = function (k) {
if (this.size == 0) return [];
k = Math.min(this.size, k);
var fpq = new FastPriorityQueue(this.compare);
const newSize = Math.min((k > 0 ? Math.pow(2, k - 1) : 0) + 1, this.size);
fpq.size = newSize;
fpq.array = this.array.slice(0, newSize);
var smallest = new Array(k);
for (var i = 0; i < k; i++) {
smallest[i] = fpq.poll();
}
return smallest;
}
// test:
// let queue1= new FastPriorityQueue();
// queue1.add(1);
// queue1.add(2);
// queue1.add(-1);
// console.log(queue1.peek())
// console.log(queue1.poll());
// console.log(queue1.peek())
// console.log(queue1.poll());
// console.log(queue1.peek())
// test2:
// const compareCb= (a,b)=>{
// return a.number<b.number
// }
// let queue2= new FastPriorityQueue(compareCb);
// queue2.add({
// number:100,
// name:'a',
// })
// queue2.add({
// number:101,
// name:'b',
// })
// queue2.add({
// number:200,
// name:'c',
// })
// queue2.add({
// number:10,
// name:'d',
// })
// console.log(queue2.peek())
// console.log(queue2.poll());
// console.log(queue2.peek())
// console.log(queue2.poll());
// console.log(queue2.peek())
//----------------------------------------------------------------
//----------------------------------------------------------------go
go
package main
import (
"container/heap"
"fmt"
)
type ListNode struct {
Val int
Next *ListNode
}
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// slice,api:
//map只能为slice, map, channel分配内存;
// values := [][]int{}; a := [3][4]int{{0, 1, 2, 3}, /* 第一行索引为 0 */{4, 5, 6, 7}, /* 第二行索引为 1 */{8, 9, 10, 11}, /* 第三行索引为 2 */}
// append,copy,len,[1:2];
// set,map
// map1 := map[string]string{}; delete(map1, "a"); if val, ok := map1["a"]; ok {}
// int heap;
type IntHeap []int
func (h IntHeap) Len() int { return len(h) }
//默认小根堆,大根堆类似;
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x interface{}) {
// Push and Pop use pointer receivers because they modify the slice's length,
// not just its contents.
*h = append(*h, x.(int))
heap.Fix(h, x.(int))
}
func (h *IntHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
//优先队列;
// An Item is something we manage in a priority queue.
type Item struct {
value string // The value of the item; arbitrary.
priority int // The priority of the item in the queue.
// The index is needed by update and is maintained by the heap.Interface methods.
index int // The index of the item in the heap.
}
// A PriorityQueue implements heap.Interface and holds Items.
type PriorityQueue []*Item
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
// We want Pop to give us the highest, not lowest, priority so we use greater than here.
return pq[i].priority > pq[j].priority
}
func (pq PriorityQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
pq[i].index = i
pq[j].index = j
}
func (pq *PriorityQueue) Push(x interface{}) {
n := len(*pq)
item := x.(*Item)
item.index = n
*pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
item.index = -1 // for safety
*pq = old[0 : n-1]
return item
}
// update modifies the priority and value of an Item in the queue.
func (pq *PriorityQueue) update(item *Item, value string, priority int) {
item.value = value
item.priority = priority
heap.Fix(pq, item.index)
}
//------------------------------------------------------------
//--------------------示例的main函数,可以删除-------------------
func main1() {
nums := []int{1, 2, 2, 3}
// nums := []int{6, 5, 4, 4}
// nums := []int{1, 3, 2}
fmt.Println(nums)
//堆
h := &IntHeap{2, 1, 5, 100, 3, 6, 4, 5}
fmt.Println("test", h, *h)
heap.Init(h)
heap.Push(h, 3)
// heap.Fix(h, 3)
fmt.Println(h)
fmt.Printf("minimum: %d\n", (*h)[0])
for h.Len() > 0 {
fmt.Printf("%d ", heap.Pop(h))
}
//优先队列;
// Some items and their priorities.
items := map[string]int{
"banana": 3, "apple": 2, "pear": 4,
}
// Create a priority queue, put the items in it, and
// establish the priority queue (heap) invariants.
pq := make(PriorityQueue, len(items))
i := 0
for value, priority := range items {
pq[i] = &Item{
value: value,
priority: priority,
index: i,
}
i++
}
heap.Init(&pq)
// Insert a new item and then modify its priority.
item := &Item{
value: "orange",
priority: 1,
}
heap.Push(&pq, item)
pq.update(item, item.value, 5)
// Take the items out; they arrive in decreasing priority order.
for pq.Len() > 0 {
item := heap.Pop(&pq).(*Item)
fmt.Printf("%.2d:%s \n", item.priority, item.value)
}
}
// ----------------------------------------------------------------
// ----------------------------------------------------------------
func findDuplicates(nums []int) []int {
var swap func(arr[]int , k int, j int)
swap = func (arr []int, k int, j int) {
temp := arr[j]
arr[j] = arr[k]
arr[k] = temp
}
for i:= 0; i< len(nums); i++ {
for ; nums[i] != nums[nums[i]-1]; {
swap(nums, i, nums[i]-1)
}
}
// fmt.Printf("%v",nums)
ans := []int{}
for i:= 0; i< len(nums); i++ {
if(nums[i] != i+1){
ans = append(ans, nums[i])
}
}
return ans
}
func main () {
nums :=[]int{4,3,2,7,8,2,3,1}
ans := findDuplicates(nums)
fmt.Printf("%v",ans)
}