珍惜眼前的一切,然后加油。
LeetCode #4. Median of Two Sorted Arrays
题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/
参考文献:
思路:
实在是脑子转不过来,看了一下解法,然后就把自己的理解讲一下吧。
有两个规律需要说下:
1.在某个数列头尾删去相同数量的元素,其中位数是不变的。比如[1,2,3,4]删去1和4.
2.如果两个数列的中位数是m1, m2,那么合并后的数列的中位数的值肯定在[m1,m2]范围内。
既然题目是要Log级别的复杂度,就要想到要用折半法把问题的规模降低…举个例子,假设有[1,2,4,6,6,8]和[1,5,7,8,10,25,36]两个数列,很容易算出他们的(前序 )中位数分别是4和8,而他们合并后的中位数的值在[4,8]之间。
然后可以删去无用的值,[1,2]与[10,25,36]. 但由于规律1的限制,如果后面删了3个的话,合并后删减的数列会发生变化(本例中奇偶性都变了),我们只能删去min(2,3)=2个元素…这种删值从理论上讲就是折半了,然后搞一波递归就行了。
最最最基本的思路如下:
两个有序数列Ary1, Ary2(假设升序排列)的中位数分别为m1,m2
if m1 == m2:
LUCKY!!!
elif m1 < m2:
取(Ary1的后半段,Ary2的前半段)再算
else
取(Ary1的前半段,Ary2的后半段)再算
由于题设里面俩数组是不等长的,所以里对其中某个数组n<=2时处理方法需要注意…
代码:
int max(int x, int y) {
return x>y ? x : y;
}
int min(int x, int y) {
return x<y ? x : y;
}
double getMedian(int* nums, int size) {
if (size == 0)
return -1;
if (size % 2 == 0) {
//Even number
return (nums[size / 2] + nums[size / 2 - 1]) / 2.0;
}
else {
return nums[(size - 1) / 2];
}
}
double findMedianMerge(int* nums1, int nums1Size, int* nums2, int nums2Size) {
int count = 0;
int n1Count = 0;
int totalSize = nums1Size + nums2Size;
int t1, t2;
if (totalSize % 2 == 0) {
t1 = totalSize / 2;
t2 = t1 + 1;
}
else {
t1 = -1;
t2 = totalSize / 2 + 1;
}
double sum = 0;
int curVal;
while (n1Count < nums1Size) {
if (*nums1 < *nums2) {
n1Count++;
curVal = *nums1;
nums1++;
}
else {
curVal = *nums2;
nums2++;
}
count++;
if (count == t1 || count == t2) {
sum += curVal;
}
else if (count >= t2) {
break;
}
}
if (count < t1) {
//Not finished
nums2 += (t1 - count - 1);
count = t1;
sum += *nums2;
nums2++;
}
if (count < t2) {
nums2 += (t2 - count - 1);
sum += *nums2;
}
if (t1 == -1)
return sum;
else
return sum / 2.0;
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
int totalSize = nums1Size + nums2Size;
if (nums1Size > nums2Size) {
//Keep ary1 shorter than ary2
int* temp = nums1;
int t = nums1Size;
nums1 = nums2;
nums1Size = nums2Size;
nums2 = temp;
nums2Size = t;
}
if (nums1Size == 0) {
return getMedian(nums2, nums2Size);
} else if (nums1Size == 1) {
if (nums2Size == 1) {
return (nums1[0] + nums2[0]) / 2.0;
}
else {
return findMedianMerge(nums1, nums1Size, nums2, nums2Size);
}
}
else if (nums1Size == 2) {
if (nums2Size == 2) {
return (max(nums1[0], nums2[0]) + min(nums1[1], nums2[1])) / 2.0;
}
else {
return findMedianMerge(nums1, nums1Size, nums2, nums2Size);
}
}
//Slice
double m1 = getMedian(nums1, nums1Size);
double m2 = getMedian(nums2, nums2Size);
if (m1 == m2) {
//Got lucky
return m1;
}
else if (m1 < m2) {
//Slice L-nums1 and R-nums2
int cut = (nums1Size - 1) / 2;
return findMedianSortedArrays(nums1 + cut, nums1Size - cut, nums2, nums2Size - cut);
}
else {
//Slice R-nums1 and L-nums2
int cut = (nums1Size - 1) / 2;
return findMedianSortedArrays(nums1, nums1Size - cut, nums2 + cut, nums2Size - cut);
}
}
SS客户端及使用教程
2016-03-02更新Windows客户端版本至3.0 2017-03-16更新客户端版本
准备工作:
- 下载SS客户端,方便的话可以访问https://shadowsocks.org/en/download/clients.html 自行下载,有Windows/MacOS/Android/iOS客户端。
- Windows用户也可下载这个稳定版链接: http://pan.baidu.com/s/1mhEkW3I 密码: kk22
- 如果修改过hosts文件,确保您已经将HOSTS文件恢复原样
- 如果设置过浏览器代理插件/GoAgent等,也全部禁用掉
使用步骤:
1.进入SS服务的用户面板,点击左侧“节点列表”

2.挑选需要的节点,然后点击“操作”->“二维码”

点击后会新开个网页,上面有二维码,不要动它
3.打开SS客户端,此时任务栏右下角会有小飞机图标。鼠标右键,弹出的菜单点击“服务器”,然后“扫描屏幕上的二维码”

正常的话就能扫描好屏幕的上的二维码了,就是服务器账户信息
4.还是刚才的右键菜单,点“启动系统代理”
然后“系统代理模式”选择“PAC”模式
最后一步,在“PAC”那边,点击“从GFWList更新本地PAC”
记得定期更新PAC列表,否则请直接使用“全局模式”。
如果过几秒提示“更新PAC成功”,就一切搞定啦!
Protected: 玖
LeetCode #237. Delete Node in a Linked List
题目:https://leetcode.com/problems/delete-node-in-a-linked-list/
思路:
因为只给要删去节点的指针,所以就要想点歪办法。
假设我们有节点1,2,3,【4】,5,6,要删去4这个点,那其实只要把后序节点5的值复制给4,然后我们可以把后面原来那个5删掉,把原有的4节点链到6就行了~大致意思就是,通过往前复制一个值,构造出一个新的“4”的前序节点。
使用前:1,2,3,[4],5,6 拷贝值:1,2,3,5,[5],6 删去多于节点(将新的5节点链接到拷贝的5右边的6,删去老的5节点):1,2,3,5,6
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
ListNode* nextNode = node->next;
node->val = nextNode->val; //Copy value
ListNode* thirdNode = nextNode->next;
node->next = thirdNode;
delete nextNode;
}
};
LeetCode #104. Maximum Depth of Binary Tree
题目:https://leetcode.com/problems/maximum-depth-of-binary-tree/
思路:就是个树遍历的东西,很简单地可以用递归实现
代码:
/**
* 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 {
public:
int maxDepth(TreeNode* root) {
// Left - N - Right
if(root == NULL) {
return 0;
} else {
//Non-empty
int leftDeep = 1 + maxDepth(root->left);
int rightDeep = 1 + maxDepth(root->right);
if(leftDeep > rightDeep)
return leftDeep;
else
return rightDeep;
}
}
};
Cisco Linksys EA3500 刷入OpenWrt
万万没想到这个路由器现在也有了官方的OpenWrt支持!
可以参考这里(英文):https://wiki.openwrt.org/toh/linksys/ea3500
大致翻译如下:
As of r47458 the EA3500 is completely supported. This model is identified by the board codename “Audi.”
自从版本r47458开始,EA3500已被OpenWrt完整支持了。这个机型的固件可以用识别码 “Audi”查找
访问这里可以得到最新的编译版本:https://downloads.openwrt.org/snapshots/trunk/kirkwood/generic/
需要查找带有
openwrt-kirkwood-linksys-audi-squashfs-factory.bin
字样的,是可以直接用思科原版固件刷入的;而
openwrt-kirkwood-linksys-audi-squashfs-sysupgrade.tar
是从旧版本OpenWrt升级用的。
注意:刷好之后默认没有开启无线的,也没有装luci图形界面,需要用ssh(可通过putty软件)用有线的方式连接到管理界面。路由器默认的IP地址应该是192.168.1.1
连接SSH时,默认用户是root,然后是空密码。进入后需要用
passwd
命令设置密码。
然后可以更新opkg包进而安装网页管理界面luci
opkg update #更新包信息 opkg install luci #下载并安装luci opkg install luci-i18n-base-zh-cn #可选,安装中文语言
LeetCode #2.Add Two Numbers
链接:https://leetcode.com/problems/add-two-numbers/
思路:
两条链表,从其中一段开始修改,直接在原有节点上做加法。碰到其中一条结束的时候,如果另一条还在继续,则把next指向另一条链表往后一个节点(感觉像是铁轨并轨一样)。
注意如果加起来还有多,要新建一个节点存放。
代码:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* retNode = l1;
ListNode* prevNode = NULL;
int res = 0;
while (l1 != NULL && l2 != NULL) {
l1->val += (l2->val + res);
res = 0;
while (l1->val >= 10) {
l1->val -= 10;
res += 1;
}
prevNode = l1;
l1 = l1->next;
l2 = l2->next;
}
if (res == 0 && l1 == NULL && l2 == NULL)
return retNode;
ListNode* currNode = l1;
if (l1 == NULL) {
prevNode->next = l2;
currNode = l2;
}
while (currNode != NULL && res != 0) {
currNode->val += res;
res = 0;
while (currNode->val >= 10) {
currNode->val -= 10;
res += 1;
}
prevNode = currNode;
currNode = currNode->next;
}
if (res > 0) {
//Add Node
ListNode* endNode = new ListNode(res);
prevNode->next = endNode;
}
return retNode;
}
};
LeetCode OJ #292. Nim Game
原题地址:https://leetcode.com/problems/nim-game/
思路:
这题目是个找规律的题,号称全OJ最简单….通过找规律可以发现,当n为4的倍数时,无论如何自己都赢不了…然后搞定了
代码:
class Solution {
public:
bool canWinNim(int n) {
if(n%4 == 0)
return false;
return true;
}
};
LeetCode OJ #1 Two Sum
恩,据说刷LeetCode比较好玩,于是乎从第一题开始吧。
题目:
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
思路:
这道题给的Hint是二叉树,我有点不太懂,用二叉树实现了一个版本,不过会超时。想了下还是用map的黑科技吧,反正没限制内存大小。(再黑科技一点可以直接用数组,就是数据多的话要找到最小/最大值做好映射)
代码:
class Solution {
private:
map<int, int> valTable;
public:
vector<int> twoSum(vector<int>& nums, int target) {
for (int i = 0; i < nums.size(); i++) {
int val = nums[i];
valTable[val] = i + 1;
}
for (int i = 0; i < nums.size(); i++) {
int ne = target - nums[i];
map<int, int>::iterator result = valTable.find(ne);
if (result != valTable.end()) {
int nextIndex = result->second;
int currIndex = i + 1;
if (currIndex == nextIndex)
continue;
vector<int> retIndices;
if (currIndex > nextIndex) {
retIndices.push_back(nextIndex);
retIndices.push_back(currIndex);
}
else {
retIndices.push_back(currIndex);
retIndices.push_back(nextIndex);
}
return retIndices;
}
}
}
};
运行结果:
我只超过了30.19%的队友,哈哈~

2018 refined (beats 92.29%):
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, size_t> num_indices; // <number, indices>
for (size_t i = 0; i < nums.size(); ++i)
{
auto num = nums[i];
if (num_indices.count(target - num) > 0)
{
return {num_indices[target - num], i};
}
num_indices[num] = i;
}
return {-1, -1};
}
};

