- 有效電話號碼
給定一個包含電話號碼列表(一行一個電話號碼)的文本文件 file.txt,寫一個 bash 腳本輸出所有有效的電話號碼。你可以假設一個有效的電話號碼必須滿足以下兩種格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一個數字)你也可以假設每行前後沒有多餘的空格字符。
正則表達式的重點有三:特殊字符、限定字符、定位符
表達 (xxx) xxx-xxxx
^\([0-9][0-9][0-9]\) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$
使用限定符來限定數字出現的次數,優化爲如下表達
^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$
表達 xxx-xxx-xxxx
^[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$
使用限定符來限定數字出現的次數,優化爲如下表達
^[0-9]{3}-[0-9]{3}-[0-9]{4}$
綜合起來,使用特殊字符()和|。用()來標記一個表達式,使用|來指明兩項之間的任意選擇。
# Read from the file file.txt and output all valid phone numbers to stdout.
awk '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/' file.txt
- 轉置文件
給定一個文件 file.txt,轉置它的內容。
你可以假設每行列數相同,並且每個字段由 ’ ’ 分隔.
awk是一行一行地處理文本文件,運行流程是:
先運行BEGIN後的{Action},相當於表頭
再運行{Action}中的文件處理主體命令
最後運行END後的{Action}中的命令
有幾個經常用到的awk常量:NF是當前行的field字段數;NR是正在處理的當前行數。
注意到是轉置,假如原始文本有m行n列(字段),那麼轉置後的文本應該有n行m列,即原始文本的每個字段都對應新文本的一行。我們可以用數組res來儲存新文本,將新文本的每一行存爲數組res的一個元素。
在END之前我們遍歷file.txt的每一行,並做一個判斷:在第一行時,每碰到一個字段就將其按順序放在res數組中;從第二行開始起,每碰到一個字段就將其追加到對應元素的末尾(中間添加一個空格)。
文本處理完了,最後需要輸出。在END後遍歷數組,輸出每一行。注意printf不會自動換行,而print會自動換行。
# Read from the file file.txt and print its transposed content to stdout.
awk '{
for (i=1;i<=NF;i++){
if (NR==1){
res[i]=$i
}
else{
res[i]=res[i]" "$i
}
}
}END{
for(j=1;j<=NF;j++){
print res[j]
}
}' file.txt
- 第十行
給定一個文本文件 file.txt,請只打印這個文件中的第十行。
# Read from the file file.txt and output the tenth line to stdout.
awk 'NR == 10{print $0}' file.txt
- 刪除重複的電子郵箱
# Write your MySQL query statement below
DELETE p1 FROM Person p1,
Person p2
WHERE
p1.Email = p2.Email AND p1.Id > p2.Id
- 上升的溫度
給定一個 Weather 表,編寫一個 SQL 查詢,來查找與之前(昨天的)日期相比溫度更高的所有日期的 Id。
# Write your MySQL query statement below
SELECT a.Id
FROM (
SELECT w.Id, w.Temperature
, if(w.Temperature > @last_T
AND datediff(w.RecordDate, @last_D) = 1, 1, 0) AS is_greater
, @last_T := w.Temperature, @last_D := w.RecordDate
FROM Weather w, (
SELECT @last_T := 100, @last_D := 1
) b
ORDER BY RecordDate ASC
) a
WHERE a.is_greater = 1
ORDER BY a.Id ASC
- 打家劫舍
給定一個代表每個房屋存放金額的非負整數數組,計算你 不觸動警報裝置的情況下 ,一夜之內能夠偷竊到的最高金額。如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
本題是簡單的動態規劃問題,每一個位的狀態取決於是否選擇偷竊該位,如果偷竊則爲dp[i - 2] + nums[i],否則爲dp[i - 1]
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if (n == 0)
return 0;
if (n == 1)
return nums[0];
int ret = 0, i = 2;
vector<int> dp(nums);
if (dp[1] < dp[0])
dp[1] = dp[0];
while (i < n)
{
dp[i] = max(dp[i - 2] + nums[i], dp[i -1]);
i++;
}
return dp[n - 1];
}
};
- 二叉樹的右視圖
給定一棵二叉樹,想象自己站在它的右側,按照從頂部到底部的順序,返回從右側所能看到的節點值。
本題可通過DFS和BFS求解。DFS的話根->右子樹->左子樹的順序遍歷,如果該深度已輸出則不在繼續存儲。BFS的話逐層遍歷,每層最後的元素即爲右視圖
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
vector<int> ret;
public:
vector<int> rightSideView(TreeNode* root) {
dfs(root, 0);
//bfs(root);
return ret;
}
void dfs(TreeNode *node, int depth)
{
if (node == NULL) return;
if (depth == ret.size())
{
ret.push_back(node->val);
}
depth++;
dfs(node->right, depth);
dfs(node->left, depth);
}
void bfs(TreeNode *node)
{
queue<TreeNode *> line;
if (node == NULL) return;
line.push(node);
while (line.size())
{
int size = line.size();
for (int i = 0; i < size; i++)
{
TreeNode *now = line.front();
line.pop();
if (now->left) line.push(now->left);
if (now->right) line.push(now->right);
if (i == size - 1) ret.push_back(now->val);
}
}
}
};