Categories
不学无术

LeetCode #100. Same Tree

题目:https://leetcode.com/problems/same-tree/
分析:注意判断NULL情况,用递归做
代码:(秒AC有木有!)

/**
 * 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:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p == NULL && q == NULL)
            return true;
        if(p == NULL || q == NULL)
            return false;
        if(p->val != q->val)
            return false;
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
};

 

Categories
不学无术

LeetCode #226. Invert Binary Tree

题目:https://leetcode.com/problems/invert-binary-tree/
思路:这TM还要思路?
代码:

/**
 * 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:
    TreeNode* invertTree(TreeNode* root) {
        if(root == NULL)
            return root;
        TreeNode *tmpNode = root->right;
        root->right = root->left;
        root->left = tmpNode;
        if(root->left != NULL)
            invertTree(root->left);
        if(root->right != NULL)
            invertTree(root->right);
        return root;
    }
};

 

Categories
不学无术

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);
	}
}

 

Categories
不学无术

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;
    }
};

 

Categories
不学无术

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;
        }
    }
};

 

Categories
不学无术

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;
	}
};

结果:
LeetCode002

Categories
不学无术

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;
    }
};

 

Categories
不学无术

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%的队友,哈哈~
LeetCode_Twp_Sum
 
 
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};
    }
};