Programming Skills
Here, you will see an obsessive coding lover sharing interesting programming problems and skills.
Remove K Digits
[題目]
Given string num representing a non-negative integer num, and an integer k, return the smallest possible integer after removing k digits from num.
Example 1:
Input: num = "1432219", k = 3 Output: "1219" Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
[Solution]
Use a stack with N-K size to store the answer. Bottom is most sign digit. Top is less sign digit.
1.Since original size of number is N, and we can remove K digits from it. The best choice is to remove exactly K digits. It makes the answer lower.
2.Use a stack to put answer. Stack bottom represent the most sign digit. Stack top represent the less sign digit.
Decide digit[0]~digit[i] should stay or not according to digit[i+1].
New we are pushing digit into stack.
1.When push d[0] to stack, we don't know if d[0] is a good choice for most sign digit or not. But let's assume it is (we don't have choice actually, we can't just remove d[0] without more information). So we just push d[0] into stack, and wait for more info.
2.When push d[1] to stack, there is two condition :
a. d[0] <= d[1] : d[0] is lower, so d[0] is better than d[1] to be a most sign digit. Then we just simply push(d[1]).
b. d[0] > d[1] : d[1] is lower than d[0], which makes it a better choice for that slot, so we let d[1] take d[0]'s place.
We pop d[0] and push d[1], so d[1] replace d[0] and become bottom of stack, and most sign digit.
2.b is the most important step. The core concept is : "We should not allow the big number take the most sign place. So if d[i+1] is smaller(better) than d[i](which is at stack.top()), we should pop d[i] out. Furthermore, we should pop stack continuously until stack.top() is smaller or equal to d[i+1]. "
[code]
public:
string removeKdigits(string num, int k) {
string maxS;
for (auto ch : num){
while(!maxS.empty() && maxS.back() > ch && k > 0){
maxS.pop_back();
k--;
}
maxS.push_back(ch);
}
//if still barging chip K left, then we start pop from back(the most biggest number)
while (k-->0) maxS.pop_back();
bool foundFirstNonZero=false;
string ans;
for (auto ch : maxS){
if(ch!='0') foundFirstNonZero=true;
if(foundFirstNonZero){
ans +=ch;
}
}
return ans.empty() ? "0" : ans;
}
};
Next Greater Element 1
Next Greater Element 1
The next greater element of some element x in an array is the first greater element that is to the right of x in the same array.
You are given two distinct 0-indexed integer arrays nums1 and nums2, where nums1 is a subset of nums2.
For each 0 <= i < nums1.length, find the index j such that nums1[i] == nums2[j] and determine the next greater element of nums2[j] in nums2. If there is no next greater element, then the answer for this query is -1.
Return an array ans of length nums1.length such that ans[i] is the next greater element as described above.
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2] Output: [-1,3,-1] Explanation: The next greater element for each value of nums1 is as follows: - 4 is underlined in nums2 = [1,3,4,2]. There is no next greater element, so the answer is -1. - 1 is underlined in nums2 = [1,3,4,2]. The next greater element is 3. - 2 is underlined in nums2 = [1,3,4,2]. There is no next greater element, so the answer is -1.
[Solution]
Steps :
1. Find "Next greater element" for all element in nums2.
2. Use a hash map to record <value, next greater element value>
And the most difficult and important is step 1.
A.Pop them is safe, because they are smaller than 'e', so useless for 'e' and all elements on the left of 'e'.
check 3's NGE : we got '4', and monoS became (3,4]
點亮LED
有參考到網路上前輩的文章
http://drho.club/2017/12/arduino-unit-2/
[組裝]
[基本觀念]
想點亮一個LED, 當然就要給他供電
所以取出一個LED component
然後把一腳接GND, 另一腳接正電壓就會亮了
然後分別討論這幾個元素要從哪來
[1.電]
Arduino的pin可以提供5V的正電壓
只要用選一個pin(例如pin 10)
然後用函式
pinMode(12, OUTPUT); //定义数字接口11 为输出
digitalWrite(12,HIGH);//輸出5v電壓
即可
[2.GND]
板子上有一個pin是"GND"
[3.電阻]
我們還需要一個限流電阻,原因是Arduino的輸出電壓是5V大於LED的工作電壓,限流電阻可以讓在LED上工作的電壓降低,可以避免LED被過大的電流燒毀。(電阻值大小有一定的計算公式,每一種LED需要的電阻值不一定相同。一般來說,只要大於220歐姆即可運作,如果使用的電阻值過大,頂多就是亮度較低或是不會亮而已)
[程式]
void setup()
{
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
}
void loop()
{
}
First Time Arduino
雖然耳聞多年但一直沒有玩過
今天就來好好地把玩一下
[設備]
[arduino uno 3]
[usb type A to type B]
[流程]
真的是超級簡單
1.到官網下載arduino IDE
https://www.arduino.cc/en/Main/Software
像我是win10上作業, 就點選
"Windows app"
然後全部無腦安裝, 甚麼都不用選
2.連接電腦
把arduino用usb線連接到電腦上
(由於出廠時有預先燒錄program進去了
所以你會看到一個綠燈恆亮, 黃燈閃爍這是正常的)
3.打開IDE
Tool-->serial port-->選com8(理論上只有一個可以選, 我的是com8, 你是別的也無所謂)
好了到這步已經可以開始寫code了
[測試一下]
測試也是超級簡單
IDE有內建許多測試程式讓你直接使用, 都不用自己寫
1.程式碼
File-->Example-->Basic-->blink
選完後你會發現他開啟一個視窗, 把內建的程式碼打開了
這是一個讓黃色LED閃爍的程式
2.編譯與上傳
IDE左上角有一個"向右的箭頭", 滑鼠移上去會寫"upload"("上傳")
按下去後會進行編譯-->上傳
上傳完畢tx和rx兩個LED會快速閃一兩秒
然後arduino就會開始程式了
你會看到黃色LED一直閃爍(只要你電還插著就一直閃)
Abstract Factory
1.有很多種factory(例如audi, BMW)
2.一個factory可以生產多種東西, 但是彼此關聯的(例如car, wheel)
所以factory的public API會有多個
car* createCar()
wheel* createWheel()
4.不同廠牌的車子用不同的xxxFactory創建, (close for modification)
Factory Pattern
Strategy Pattern
你的主體context, 擁有一個strategy指標, 可以動態指向不同的strategy實體
#include <iostream>
using namespace std;
class Strategy{ //interface
public:
virtual void execute() = 0;
};
class ConcreteStrategy1 : public Strategy{
public:
void execute(){
cout << "run Strategy 1" << endl;
}
};
class ConcreteStrategy2 : public Strategy{
public:
void execute(){
cout << "run Strategy 2" << endl;
}
};
class Context{
private:
Strategy* mystg;
public:
Context(Strategy* stg) : mystg(stg){}
void setstg(Strategy* stg){
delete mystg;
mystg = stg;
}
void runstg(){
mystg->execute();
}
};
int main(int argc, char** argv) {
Context c1(new ConcreteStrategy2());
c1.runstg();
c1.setstg(new ConcreteStrategy1());
c1.runstg();
return 0;
}
template pattern
class AbstractClass{
public:
void executeSteps(){
step1();
step2();
}
virtual void step1() = 0;
virtual void step2() = 0;
};
class Concrete1: public AbstractClass{
public :
void step1(){
cout << "您好" << endl;
}
void step2(){
cout << "遞上中文菜單" << endl;
}
};
class Concrete2: public AbstractClass{
public :
void step1(){
cout << "hello" << endl;
}
void step2(){
cout << "present english menu" << endl;
}
};
int main(int argc, char** argv) {
AbstractClass* chinese = new Concrete1();
AbstractClass* english = new Concrete2();
chinese->executeSteps();
english->executeSteps();
return 0;
}
用Template Pattern的好處是:
1.今天你想支援法語的功能, 只要多寫一個Concrete Class3即可
這滿足了Open for extension
2.今天你新增法語功能的時候, 不會動到Concrete Class1/2與Abstract Class
這滿足了Close for modification
3.今天你想顛倒步驟順序, 改為先上菜單再說歡迎, 你只要改executeSteps()
就可以同時套用到中文, 英語, 法語
不用改三次
Image overlap
https://leetcode.com/problems/image-overlap/
Input: A = [[1,1,0],
[0,1,0],
[0,1,0]]
B = [[0,0,0],
[0,1,1],
[0,0,1]]
Output: 3
Explanation: We slide A to right by 1 unit and down by 1 unit.
1. 1 <= A.length = A[0].length = B.length = B[0].length <= 30
2. 0 <= A[i][j], B[i][j] <= 1
如果貼合時A and B同一位置中的元素都是1,就得一分。
Input: A = [[1,1,0],
[0,0,0],
[0,0,0]]
B = [[0,0,0],
[0,1,1],
[0,0,1]]
For Red '1' on A(0,0).We can score from one of these movements: (+1,+1) or (+1,+2) or (+2,+2)
For Blue '1' on A(0,1).
We can score from one of these movements: (+1,+0) or (+1,+1) or (+2,+1)
[Implement]
1.We transform "movements" to "integers":
(delta R, delta C) ---> delta R*100 + delta C
(+3,-2) --> 3*100 - 2
2.We use the interger(represent movement) as the hashkey
And use hash table unordered_map<int, score> to record score of movement.
Of course there is another way, such as using 'String' as the hashkey.
Then use hash table unordered_map<string, score> to record score of movement.
int largestOverlap(vector<vector<int>>& A, vector<vector<int>>& B) {
//record the coordinate of all the '1' in A
//record the coordinate of all the '1' in B
vector<pair<int,int>> A1;
vector<pair<int,int>> B1;
for(int r=0;r<A.size();r++)
for(int c=0;c<A[0].size();c++){
if(A[r][c]==1) A1.push_back(pair<int,int>(r,c));
if(B[r][c]==1) B1.push_back(pair<int,int>(r,c));
}
//Step1: For all '1' in A, find all the movements which we can get score from it.
unordered_map<int, int> ht;
for(auto ca:A1){
for(auto cb:B1){
int hashkey=(ca.first-cb.first)*100
+(ca.second-cb.second);
ht[hashkey]++;
}
}
//Step 2: For all movements found in step1, find the one who scores most. Return the score.
int ans=0;
for(auto it:ht){
ans = max(ans,it.second);
}
return ans;
}
Contains Duplicate II
https://leetcode.com/problems/contains-duplicate-ii/
Input: nums = [1,2,3,1], k = 3 Output: true
Input: nums = [1,0,1,1], k = 1 Output: true
Input: nums = [1,2,3,1,2,3], k = 2 Output: false
[Solution]
Let's say k=3, then you should use a sliding window with size 4(=k+1) to scan the input array.
If two elements in the sliding window are identical,
it means they are identical and their distance is no greater than 3.
And you should return True under that condition.
If you scan through the entire array and nothing happen, then return False.
About the implementation, using STL "set" as the sliding window is a good idea.
During "sliding",
1.Remove the left element from window(because the window is moving to the right)
2.Check if the right element is identical to any one in the window.(return True if exist.)
3.Add the right element into the window


