hash & heap - 20181023 - 20181026

本文深入探讨了数据结构如链表、散列表、优先队列的高级应用,包括链表哈希表扩容、LRU缓存设计、优先队列在解决特定问题中的技巧等,覆盖了从基础数据结构到复杂算法的全面内容。

129. Rehashing

 1 /**
 2  * Definition for ListNode
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) {
 7  *         val = x;
 8  *         next = null;
 9  *     }
10  * }
11  */
12 
13 public class Solution {
14     /**
15      * @param hashTable: A list of The first node of linked list
16      * @return: A list of The first node of linked list which have twice size
17      */
18     public ListNode[] rehashing(ListNode[] hashTable) {
19         // write your code here
20         if (hashTable.length == 0) {
21             return hashTable;
22         }
23         int capacity = hashTable.length * 2;
24         ListNode[] result = new ListNode[capacity];
25         for (ListNode listNode : hashTable) {
26             while (listNode != null) {
27                 int newIndex = (listNode.val % capacity + capacity) % capacity;
28                 if (result[newIndex] == null) {
29                     result[newIndex] = new ListNode(listNode.val);
30                 } else {
31                     ListNode head = result[newIndex];
32                     while (head.next != null) {
33                         head = head.next;
34                     }
35                     head.next = new ListNode(listNode.val);
36                 }
37                 listNode = listNode.next;
38             }
39         }
40         return result;
41     }
42 };
View Code

 

134. LRU Cache

 1 class Node {
 2     int key;
 3     int value;
 4     Node next;
 5 
 6     Node(int key, int value) {
 7         this.key = key;
 8         this.value = value;
 9         this.next = null;
10     }
11 }
12 
13 public class LRUCache {
14     int size;
15     int capacity;
16     Node tail;
17     Node dummy;
18     Map<Integer, Node> keyToPrevMap;
19 
20     /*
21     * @param capacity: An integer
22     */
23     public LRUCache(int capacity) {
24         // do intialization if necessary
25         this.capacity = capacity;
26         this.size = 0;
27         this.dummy = new Node(0, 0);
28         this.tail = dummy;
29         keyToPrevMap = new HashMap<>();
30     }
31 
32     public void moveRecentNodeToTail(int key) {
33         Node prev = keyToPrevMap.get(key);
34         Node curr = prev.next;
35         if (curr == tail) {
36             return;
37         }
38 
39         prev.next = curr.next;
40         tail.next = curr;
41         keyToPrevMap.put(key, tail);
42         //删掉现节点之后,不仅要改变前指针指向,还需要更新map
43         if(prev.next!=null){
44             keyToPrevMap.put(prev.next.key,prev);
45         }
46         tail = curr;
47     }
48 
49     /*
50      * @param key: An integer
51      * @return: An integer
52      */
53     public int get(int key) {
54         // write your code here
55         if (keyToPrevMap.containsKey(key)) {
56             moveRecentNodeToTail(key);
57             return tail.value;
58         }
59         return -1;
60     }
61 
62     /*
63      * @param key: An integer
64      * @param value: An integer
65      * @return: nothing
66      */
67     public void set(int key, int value) {
68         // write your code here
69         if (get(key) != -1) {
70             Node prev = keyToPrevMap.get(key);
71             prev.next.value = value;
72             return;
73         }
74 
75         //无此值 set并放在队尾
76         if (size < capacity) {
77             size++;
78             Node newNode = new Node(key, value);
79             tail.next = newNode;
80             keyToPrevMap.put(key, tail);
81             tail = newNode;
82             return;
83         }
84 
85         //空间已满,需要删掉头指针: 可以直接替换头指针key-value值,再移到队尾来实现
86         Node first = dummy.next;
87         keyToPrevMap.remove(first.key);
88         first.key = key;
89         first.value = value;
90         keyToPrevMap.put(key, dummy);
91         moveRecentNodeToTail(key);
92     }
93 }
View Code

 

4. Ugly Number II

method1:用优先队列

 1 public class Solution {
 2     /**
 3      * @param n: An integer
 4      * @return: the nth prime number as description.
 5      */
 6     public int nthUglyNumber(int n) {
 7         // write your code here
 8         Queue<Long> queue = new PriorityQueue<>();
 9         Set<Long> set = new HashSet<>();
10         int[] factors = new int[3];
11 
12         factors[0] = 2;
13         factors[1] = 3;
14         factors[2] = 5;
15         queue.add(1L);
16         Long number = 0L;
17         for (int i = 0; i < n; i++) {
18             number = queue.poll();
19             for (int j = 0; j < 3; j++) {
20                 if (!set.contains(number * factors[j])) {
21                     queue.add(number * factors[j]);
22                     set.add(number * factors[j]);
23                 }
24             }
25         }
26         return number.intValue();
27     }
28 }
View Code

method2: 丑数一定是某一个丑数*2或者*3或者*5的结果,维护三个指针,例如如果该指针*2结果大于上一个丑数,指针+1

 1 public class Solution {
 2     /**
 3      * @param n: An integer
 4      * @return: the nth prime number as description.
 5      */
 6     public int nthUglyNumber(int n) {
 7         // write your code here
 8         List<Integer> res = new ArrayList<>();
 9         res.add(1);
10         int p2 = 0;
11         int p3 = 0;
12         int p5 = 0;
13         for (int i = 1; i < n; i++) {
14             int lastNum = res.get(res.size() - 1);
15             while (res.get(p2) * 2 <= lastNum) p2++;
16             while (res.get(p3) * 3 <= lastNum) p3++;
17             while (res.get(p5) * 5 <= lastNum) p5++;
18             res.add(Math.min(Math.min(res.get(p2) * 2, res.get(p3) * 3), res.get(p5) * 5));
19         }
20 
21         return res.get(n - 1);
22     }
23 }
View Code

 

545. Top k Largest Numbers II

 1 public class Solution {
 2     private int maxSize;
 3     private Queue<Integer> minHeap;
 4 
 5     /*
 6     * @param k: An integer
 7     */
 8     public Solution(int k) {
 9         // do intialization if necessary
10         this.maxSize = k;
11         this.minHeap = new PriorityQueue<>();
12     }
13 
14     /*
15      * @param num: Number to be added
16      * @return: nothing
17      */
18     public void add(int num) {
19         // write your code here
20         if (minHeap.size() < maxSize) {
21             minHeap.offer(num);
22             return;
23         } 
24         if (num > minHeap.peek()) {
25             minHeap.poll();
26             minHeap.offer(num);
27         }
28     }
29 
30     /*
31      * @return: Top k element
32      */
33     public List<Integer> topk() {
34         // write your code here
35         List<Integer> res = new ArrayList<>();
36         for (Integer num : minHeap) {
37             res.add(num);
38         }
39         Collections.sort(res);
40         Collections.reverse(res);
41         return res;
42     }
43 }
View Code

 

104. Merge K Sorted Lists

method1:利用最小堆

 1 /**
 2  * Definition for ListNode.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int val) {
 7  *         this.val = val;
 8  *         this.next = null;
 9  *     }
10  * }
11  */ 
12 public class Solution {
13 
14     private Comparator<ListNode> listNodeComparator = new Comparator<ListNode>() {
15         @Override
16         public int compare(ListNode o1, ListNode o2) {
17             return (o1.val - o2.val);
18         }
19     };
20 
21     /**
22      * @param lists: a list of ListNode
23      * @return: The head of one sorted list.
24      */
25     public ListNode mergeKLists(List<ListNode> lists) {
26         // write your code here
27         if (lists == null || lists.size() == 0) {
28             return null;
29         }
30 
31         Queue<ListNode> minheap = new PriorityQueue<>(lists.size(), listNodeComparator);
32         for (ListNode node : lists) {
33             if(node != null){
34                 minheap.add(node);
35             }
36         }
37 
38         ListNode dummy = new ListNode(0);
39         ListNode tail = dummy;
40         while (!minheap.isEmpty()) {
41             ListNode head = minheap.poll();
42             tail.next = head;
43             tail = head;
44             if (head.next != null) {
45                 minheap.add(head.next);
46             }
47         }
48         return dummy.next;
49     }
50 }
View Code

method2: merge 2 by 2(待二刷)

method3: 分治(待二刷)

 
613. High Five

 1 /**
 2  * Definition for a Record
 3  * class Record {
 4  *     public int id, score;
 5  *     public Record(int id, int score){
 6  *         this.id = id;
 7  *         this.score = score;
 8  *     }
 9  * }
10  */
11 public class Solution {
12     /**
13      * @param results a list of <student_id, score>
14      * @return find the average of 5 highest scores for each person
15      * Map<Integer, Double> (student_id, average_score)
16      */
17     public Map<Integer, Double> highFive(Record[] results) {
18         // Write your code here
19         Map<Integer, Double> resMap = new HashMap<>();
20         if (results == null || results.length == 0) {
21             return resMap;
22         }
23         Map<Integer, PriorityQueue<Integer>> scoreMap = new HashMap<>();
24         for (Record record : results) {
25             if (!scoreMap.containsKey(record.id)) {
26                 scoreMap.put(record.id, new PriorityQueue<Integer>());
27             }
28 
29             PriorityQueue<Integer> heap = scoreMap.get(record.id);
30             if (heap.size() < 5) {
31                 heap.add(record.score);
32                 continue;
33             }
34 
35             if (record.score > heap.peek()) {
36                 heap.poll();
37                 heap.add(record.score);
38             }
39         }
40 
41         for (Map.Entry<Integer, PriorityQueue<Integer>> entry : scoreMap.entrySet()) {
42             PriorityQueue<Integer> scoreHeap = entry.getValue();
43             int sum = 0;
44             while (!scoreHeap.isEmpty()) {
45                 sum += scoreHeap.poll();
46             }
47             double ave = sum / 5.0;
48             resMap.put(entry.getKey(), ave);
49         }
50 
51         return resMap;
52 
53     }
54 }
View Code

 

612. K Closest Points

 1 public class Solution {
 2     /**
 3      * @param points: a list of points
 4      * @param origin: a point
 5      * @param k:      An integer
 6      * @return: the k closest points
 7      */
 8     public Point[] kClosest(Point[] points, Point origin, int k) {
 9         // write your code here
10         if (points == null || points.length < k || k == 0) {
11             return null;
12         }
13 
14         Comparator<Point> comparator = new Comparator<Point>() {
15             @Override
16             public int compare(Point o1, Point o2) {
17                 return compareDistance(o2, o1, origin);
18             }
19         };
20         Point[] res = new Point[k];
21         PriorityQueue<Point> maxHeap = new PriorityQueue<>(comparator);
22         for (Point point : points) {
23             if (maxHeap.size() < k) {
24                 maxHeap.add(point);
25                 continue;
26             }
27             if (compareDistance(point, maxHeap.peek(), origin) < 0) {
28                 maxHeap.poll();
29                 maxHeap.add(point);
30             }
31         }
32 
33         for (int i = k - 1; i >= 0; i--) {
34             res[i] = maxHeap.poll();
35         }
36         return res;
37     }
38 
39     private int compareDistance(Point o1, Point o2, Point center) {
40         int distance1 = (o1.x - center.x) * (o1.x - center.x) + (o1.y - center.y) * (o1.y - center.y);
41         int distance2 = (o2.x - center.x) * (o2.x - center.x) + (o2.y - center.y) * (o2.y - center.y);
42         if (distance1 == distance2) {
43             return o1.x != o2.x ? o1.x - o2.x : o1.y - o2.y;
44         }
45         return distance1 - distance2;
46     }
47 }
View Code

 

81. Find Median from Data Stream

 1 public class Solution {
 2     /**
 3      * @param nums: A list of integers
 4      * @return: the median of numbers
 5      */
 6 
 7     //此题中位数定义和一般的有区别,写的时候需要注意
 8     //存储后半部分的数据
 9     private PriorityQueue<Integer> minHeap;
10     //存储前半部分的数据
11     private PriorityQueue<Integer> maxHeap;
12     private int count;//已加入的数
13 
14     public int[] medianII(int[] nums) {
15         // write your code here
16         if (nums == null || nums.length == 0) {
17             return null;
18         }
19         int len = nums.length;
20         int[] res = new int[len];
21         Comparator<Integer> maxComparator = new Comparator<Integer>() {
22             @Override
23             public int compare(Integer o1, Integer o2) {
24                 return o2.compareTo(o1);
25             }
26         };
27         minHeap = new PriorityQueue<>(len);
28         maxHeap = new PriorityQueue<>(len, maxComparator);
29         for (int i = 0; i < len; i++) {
30             addNumber(nums[i]);
31             res[i] = getMedian();
32         }
33 
34         return res;
35     }
36 
37     public void addNumber(int num) {
38         maxHeap.add(num);
39         count++;
40         //总是先add前半部分数,保证maxHeap.size()>=minHeap.size()
41         if (count % 2 == 1) {
42             if (minHeap.isEmpty()) {
43                 return;
44             }
45 
46             //交换堆顶,保证有序
47             if (maxHeap.peek() > minHeap.peek()) {
48                 int maxPeek = maxHeap.poll();
49                 int minPeek = minHeap.poll();
50                 minHeap.add(maxPeek);
51                 maxHeap.add(minPeek);
52             }
53             
54             return;
55         }
56         //当count为奇数时,maxHeap.size-minHeap.size=1,因而当count变为偶数时,只用无脑再将peek取出添到后半部分
57         minHeap.add(maxHeap.poll());
58         return;
59     }
60 
61     public int getMedian() {
62         return maxHeap.peek();
63     }
64 }
View Code

 

401. Kth Smallest Number in Sorted Matrix

此题注意应该维护的是最小堆,很容易误判成最大堆

 1 class Pair {
 2     private int x;
 3     private int y;
 4     private int val;
 5 
 6     public Pair(int x, int y, int val) {
 7         this.x = x;
 8         this.y = y;
 9         this.val = val;
10     }
11 
12     public int getX() {
13         return x;
14     }
15 
16     public void setX(int x) {
17         this.x = x;
18     }
19 
20     public int getY() {
21         return y;
22     }
23 
24     public void setY(int y) {
25         this.y = y;
26     }
27 
28     public int getVal() {
29         return val;
30     }
31 
32     public void setVal(int val) {
33         this.val = val;
34     }
35 }
36 
37 public class Solution {
38     /**
39      * @param matrix: a matrix of integers
40      * @param k:      An integer
41      * @return: the kth smallest number in the matrix
42      */
43     public int kthSmallest(int[][] matrix, int k) {
44         // write your code here
45         if (matrix == null || matrix.length == 0 || matrix.length * matrix[0].length < k) {
46             return -1;
47         }
48         Comparator<Pair> comparator = new Comparator<Pair>() {
49             @Override
50             public int compare(Pair o1, Pair o2) {
51                 return o1.getVal() - o2.getVal();
52             }
53         };
54         int r = matrix.length;
55         int c = matrix[0].length;
56         PriorityQueue<Pair> minHeap = new PriorityQueue<>(comparator);
57         boolean[][] visited = new boolean[r][c];
58 
59         minHeap.add(new Pair(0, 0, matrix[0][0]));
60         visited[0][0] = true;
61 
62         for (int i = 1; i <= k - 1; i++) {
63             Pair cur = minHeap.poll();
64             if (cur.getX() + 1 < r && !visited[cur.getX() + 1][cur.getY()]) {
65                 minHeap.add(new Pair(cur.getX() + 1, cur.getY(), matrix[cur.getX() + 1][cur.getY()]));
66                 visited[cur.getX() + 1][cur.getY()] = true;
67             }
68             if (cur.getY() + 1 < c && !visited[cur.getX()][cur.getY() + 1]) {
69                 minHeap.add(new Pair(cur.getX(), cur.getY() + 1, matrix[cur.getX()][cur.getY() + 1]));
70                 visited[cur.getX()][cur.getY() + 1] = true;
71             }
72         }
73 
74         return minHeap.peek().getVal();
75     }
76 }
View Code

转载于:https://www.cnblogs.com/lizzyluvcoding/p/9836734.html

``` /** * Note: The returned array must be malloced, assume caller calls free(). */ struct hash_stable{ int key; int val; UT_hash_handle hh; }; typedef struct hash_stable* hash_ptr; struct pair{ int first; int second; }; struct pair* heap; int heapSize; void swap(struct pair*a,struct pair *b){ struct pair t=*a; *a=*b; *b=t; } bool cmp(struct pair* a,struct pair* b){ return a-&gt;second&lt;b-&gt;second; } struct pair top(){ return heap[1]; } void push(hash_ptr x){ //先放入栈尾 heap[++heapSize].first=x-&gt;key; heap[heapSize].second=x-&gt;val; int p=heapSize; while(p&gt;1){ int s=p&gt;&gt;1;//s为p的父节点 if(cmp(&amp;heap[s],&amp;heap[p]))return;//父节点更小则不需要换 swap(&amp;heap[s],&amp;heap[p]); p=s; } } //取出堆顶 void pop(){ heap[1]=heap[heapSize--];//将堆尾放入堆顶,在调整 int p=1; while((p&lt;&lt;1)&lt;=heapSize){ int s=p&lt;&lt;1; if(s&lt;heapSize&amp;&amp;cmp(&amp;heap[s+1],&amp;heap[s]))s++;//右孩子小于左孩子更小 if(cmp(&amp;heap[p],&amp;heap[s]))return; swap(&amp;heap[p],&amp;heap[s]); p=s; } } int* topKFrequent(int* nums, int numsSize, int k, int* returnSize) { hash_ptr head=NULL; hash_ptr p=NULL,tmp=NULL; for(int i=0;i&lt;numsSize;i++){ HASH_FIND_INT(head,&amp;nums[i],p); if(p==NULL){ p=malloc(sizeof(struct hash_stable)); p-&gt;key=nums[i]; p-&gt;val=1; HASH_ADD_INT(head,key,p); } else{ p-&gt;val++; } } heap=malloc(sizeof(struct pair)*(k+1)); heapSize=0; HASH_ITER(hh,head,p,tmp){ if(heapSize==k){ struct pair tmp=top(); if(tmp.second&lt;p-&gt;val){ pop(); push(p); } } else { push(p); } } *returnSize=k; int *res=malloc(sizeof(int)*k); for(int i=0;i&lt;k;i++){ struct pair tmp=top(); pop(); res[i]=tmp.first; } return res; }```添加注释并给出本题的思路
03-08
一、数据采集层:多源人脸数据获取 该层负责从不同设备 / 渠道采集人脸原始数据,为后续模型训练与识别提供基础样本,核心功能包括: 1. 多设备适配采集 实时摄像头采集: 调用计算机内置摄像头(或外接 USB 摄像头),通过OpenCV的VideoCapture接口实时捕获视频流,支持手动触发 &ldquo;拍照&rdquo;(按指定快捷键如Space)或自动定时采集(如每 2 秒采集 1 张),采集时自动框选人脸区域(通过Haar级联分类器初步定位),确保样本聚焦人脸。 支持采集参数配置:可设置采集分辨率(如 640&times;480、1280&times;720)、图像格式(JPG/PNG)、单用户采集数量(如默认采集 20 张,确保样本多样性),采集过程中实时显示 &ldquo;已采集数量 / 目标数量&rdquo;,避免样本不足。 本地图像 / 视频导入: 支持批量导入本地人脸图像文件(支持 JPG、PNG、BMP 格式),自动过滤非图像文件;导入视频文件(MP4、AVI 格式)时,可按 &ldquo;固定帧间隔&rdquo;(如每 10 帧提取 1 张图像)或 &ldquo;手动选择帧&rdquo; 提取人脸样本,适用于无实时摄像头场景。 数据集对接: 支持接入公开人脸数据集(如 LFW、ORL),通过预设脚本自动读取数据集目录结构(按 &ldquo;用户 ID - 样本图像&rdquo; 分类),快速构建训练样本库,无需手动采集,降低系统开发与测试成本。 2. 采集过程辅助功能 人脸有效性校验:采集时通过OpenCV的Haar级联分类器(或MTCNN轻量级模型)实时检测图像中是否包含人脸,若未检测到人脸(如遮挡、侧脸角度过大),则弹窗提示 &ldquo;未识别到人脸,请调整姿态&rdquo;,避免无效样本存入。 样本标签管理:采集时需为每个样本绑定 &ldquo;用户标签&rdquo;(如姓名、ID 号),支持手动输入标签或从 Excel 名单批量导入标签(按 &ldquo;标签 - 采集数量&rdquo; 对应),采集完成后自动按 &ldquo;标签 - 序号&rdquo; 命名文件(如 &ldquo;张三
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值