LeetCode

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <string>
#include <set>
#include <map>
#include <bitset>

using namespace std;

/* 链表 */
struct ListNode {
	int val;
	ListNode *next;
	static void printList(ListNode* head);
	ListNode(int x) : val(x), next(NULL) {}
};

/* 二叉树 */
struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
private:	
	/* 辅助函数 */
	double returnMedian(vector<int> nums);
	inline int expandAroundCenter(string s, int left, int right);
	string initString(string s);
	int64_t binaryConversion(string a, int n);
public:
	vector<int> twoSum(vector<int>& nums, int target);	/* 1.两数之和 */
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2);	/* 4.寻找两个有序数组的中位数 */
	string longestPalindrome(string s);	/* 5.最长回文子串(中心扩展法) */
	string Manacher(string s); /* 5.最长回文子串(马拉车算法) */
	int reverse(int x); /* 7.整数反转 */
	int myAtoi(string str); /* 8.字符串转换整数 (atoi) */
	bool isPalindrome(int x); /* 9.回文数 */
	int maxArea(vector<int>& height); /* 11.盛最多水的容器 */
	string longestCommonPrefix(vector<string>& strs); /* 14.最长公共前缀 */
	vector<vector<int>> threeSum(vector<int>& nums); /* 15.三数之和 */
	int threeSumClosest(vector<int>& nums, int target); /* 16.最接近的三数之和 */
	bool isValid(string s); /* 20.有效的括号 */
	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2); /* 21.合并两个有序链表 */
	ListNode* mergeKLists(vector<ListNode*>& lists); /* 23.合并k个排序链表 */
	int removeDuplicates(vector<int>& nums); /* 26.删除排序数组中的重复项 */
	int search(vector<int>& nums, int target); /* 33.搜索旋转排序数组 */
	int binarySearch(vector<int>& nums, int target); /* 704.二分查找 */
	vector<vector<int>> permute(vector<int>& nums); /* 46.全排列 */
	int maxSubArray(vector<int>& nums); /* 53.最大子序和 */
	vector<int> spiralOrder(vector<vector<int>>& matrix); /* 54.螺旋矩阵(遍历) */
	vector<vector<int>> generateMatrix(int n); /* 59.螺旋矩阵II(生成) */
	ListNode* rotateRight(ListNode* head, int k); /* 61.旋转链表 */
	int uniquePaths(int m, int n); /* 62.不同路径(组合) */
	int climbStairs(int n); /* 70.爬楼梯(动态规划) */
	int climbStairsWithFibonacci(int n); /* 70.爬楼梯(斐波那契数列——公式法) */
	vector<vector<int>> subsets(vector<int>& nums); /* 78.子集 */
	vector<int> grayCode(int n); /* 89.格雷编码 */
	int maxDepth(TreeNode* root); /* 104.二叉树的最大深度 */
	int maxProfit(vector<int>& prices); /* 121.买卖股票的最佳时机(最大子序和解法) */
	int maxProfit2(vector<int>& prices); /* 122.买卖股票的最佳时机II */
};

/* 2、8、16进制转10进制
 * 十进制转2-36进制直接调用函数
 * 函数原型:_itoa_s(int value, char *buffer, size_t sizeInCharacters, int radix);
 * value是输入的十进制数,buffer是存储结果,sizeInCharacters, 存放转换结果的字符串长度,radix是进制类型
 * 最后结果在buffer里
 */
int64_t Solution::binaryConversion(string a, int n) {
	if ((n != 2 && n != 8 && n != 16) || a.empty())
	{
		cout << "请输入进制数(2 or 8 or 16)||字符串不能为空" << endl;
		return -1;
	}
	int64_t ans;
	int i, t, size;
	transform(a.begin(), a.end(), a.begin(), ::toupper);      /* 将a中的小写字母转为大写字母 */
	size = a.length();  /* 求出数组a的长度 */
	ans = 0;
	for (i = 0; i < size; i++)
	{
		if (a[i] - '0' >= n && a[i] < 'A' || a[i] - 'A' + 10 >= n) /* 判断输入数与进制数是否相符合 */
		{
			cout << "输入错误." << endl;
			return -1;       /* 退出程序 */
		}
		if (a[i] >= '0'&&a[i] <= '9')  /* 判断是否为数字 */
		{
			t = a[i] - '0';
		}
		else if (n >= 11 && (a[i] >= 'A'&&a[i] <= 'A' + n - 10)) /* 判断是否为字母 */
			t = a[i] - 'A' + 10; /* 求出字母所代表的十进制数 */
		ans = ans * n + t;       /* 求出最终转换成的十进制数 */
	}
	return ans;
}

/* 打印链表 */
void ListNode::printList(ListNode* head) {
	if (nullptr == head)
		cout << "链表为空!" << endl;
	ListNode* p = head;
	while (p)
	{
		cout << p->val << "->";
		p = p->next;
	}
	cout << "NULL" << endl;
}

/* 返回有序数组nums的中位数 */
double Solution::returnMedian(vector<int> nums) {
	if (nums.empty())
		return -1;
	if (0 == nums.size() % 2)
		return (double(nums[nums.size() / 2]) + double(nums[nums.size() / 2 - 1])) / 2.0;  /* 避免两个int变量相加溢出 */
	else
		return nums[nums.size() / 2];
}

/* 返回回文串的长度 */
inline int Solution::expandAroundCenter(string s, int left, int right) {
	int L = left, R = right;
	while (L >= 0 && R < s.length() && s[L] == s[R])
	{
		L--;
		R++;
	}
	return R - L - 1;	/* 最后L--,R++了,这里要消除这个影响 */
}

/* Manacher算法中对回文串进行去除奇偶操作,返回处理后的字符串 */
string Solution::initString(string s) {
	string res = "";
	int len = s.length();
	res += '$';
	res += '#';
	for (int i = 0; i < len; ++i)
	{
		res += s[i];
		res += '#';
	}
	res += '\0';
	return res;
}

/* 因为一定有解,所以采用哈希表法 */
vector<int> Solution::twoSum(vector<int>& nums, int target) {
	if (nums.size() < 2)
		return{};

	vector<int> ans;
	unordered_map<int, int> hashTable;
	for (int i = 0; i < nums.size(); ++i)	/* 边插入边查找 */
	{
		int temp = target - nums[i];
		if (hashTable.count(temp))
		{
			ans.push_back(hashTable[temp]);
			ans.push_back(i);
			return ans;
		}
		hashTable[nums[i]] = i;
	}
	return ans;
}

/* 归并 */
double Solution::findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
	if (nums1.empty() && nums2.empty())
		return 0;
	else if (nums1.empty())
		return returnMedian(nums2);
	else if (nums2.empty())
		return returnMedian(nums1);
	else
	{
		int p1 = 0, p2 = 0;
		vector<int> res;
		while (p1 < nums1.size() && p2 < nums2.size())
		{
			if (nums1[p1] < nums2[p2])
				res.push_back(nums1[p1++]);
			else
				res.push_back(nums2[p2++]);
		}
		while (p1 < nums1.size())
			res.push_back(nums1[p1++]);
		while (p2 < nums2.size())
			res.push_back(nums2[p2++]);
		return returnMedian(res);
	}
}
/* 中心扩展法:遍历,把每个元素当做回文的中心,左右扩展记录长度
 * 注意中心一共有n+n-1=2*n-1个,考虑中心是相同两个字母的情况
 * 时间复杂度:O(n*n)
 */
string Solution::longestPalindrome(string s) {
	if (s.size() < 2)
		return s;
	int start = 0, end = 0;
	for (int i = 0; i < s.length(); ++i)
	{
		int len1 = expandAroundCenter(s, i, i);		/* 中心是一个字母 */
		int len2 = expandAroundCenter(s, i, i + 1);		/* 中心是两个相同的字母 */
		int len = (len1 > len2) ? len1 : len2;
		if (len > end - start + 1)
		{
			start = i - (len - 1) / 2;
			end = i + len / 2;
		}
	}
	return s.substr(start, end - start + 1);
}

/* Manacher算法(马拉车算法) 详见 https://segmentfault.com/a/1190000008484167/
 * 时间复杂度:O(n)
 */
string Solution::Manacher(string s) {
	string temp = initString(s);
	int id, mx = 0;
	int len = temp.length();
	int maxLen = -1, flag;
	int *p = new int[len];
	for (int i = 1; i < len - 1; ++i)
	{
		if (i < mx)
			p[i] = min(p[2 * id - i], mx - i);
		else
			p[i] = 1;
		while (temp[i - p[i]] == temp[i + p[i]])  /* 不需边界判断,因为左有'$',右有'\0' */
			p[i]++;
		/* 我们每走一步 i,都要和 mx 比较,我们希望 mx 尽可能的远,这样才能更有机会执行 if (i < mx)这句代码,从而提高效率 */
		if (mx < i + p[i])
		{
			id = i;
			mx = i + p[i];
		}
		if (maxLen < p[i] - 1)
		{
			maxLen = p[i] - 1;
			flag = i;
		}
	}
	flag = (flag - 2) / 2;	/* temp映射回s */

	delete[]p;
	return s.substr(flag - (maxLen - 1) / 2, maxLen);
}

/* 注意翻转的数要用long来储存,最后判断是否溢出 */
int Solution::reverse(int x) {
	if (0 == x)
		return x;
	long res = 0;
	while (x != 0)
	{
		res *= 10;
		res += x % 10;
		x /= 10;
	}
	if (res > INT32_MAX || res < INT32_MIN)
		return 0;
	return (int)res;
}

/* LeetCode平台有问题,同样long long类型ans*=10跑不过,vs可以跑通 */
int Solution::myAtoi(string str) {
	if (str.empty())
		return 0;
	int64_t ans = 0;
	int symbol = 1;
	bool flag = false;	/* 进入非空字符的标志 */
	for (int i = 0; i < str.length(); ++i)
	{
		if (flag && !isdigit(str[i]))
			break;
		if (str[i] != ' ')
		{
			flag = true;
			if ('-' == str[i])
				symbol = -1;
			else if ('+' == str[i])
				symbol = 1;
			else if (!isdigit(str[i]))
				break;
			else
			{
				if (ans > INT32_MAX)
				{
					if (1 == symbol)
						return INT32_MAX;
					else
						return INT32_MIN;
				}
				ans *= 10;
				ans += (int64_t)(str[i] - '0');
			}
		}
	}
	ans *= symbol;
	if (ans > INT32_MAX)
		return INT32_MAX;
	if (ans < INT32_MIN)
		return INT32_MIN;
	return (int)ans;
}

/* 与整数反转类似 */
bool Solution::isPalindrome(int x) {
	if (x < 0)
		return false;
	if (0 == x / 10)
		return true;
	int xx = x;
	long res = 0;
	while (xx > 0)
	{
		res *= 10;
		res += xx % 10;
		xx /= 10;
	}
	if (res == x)
		return true;
	return false;
}

/* 双指针 */
int Solution::maxArea(vector<int>& height) {
	if (height.size() < 2)
		return 0;
	int head = 0, tail = height.size() - 1;
	int maxValue = INT32_MIN;
	while (head < tail)
	{
		int y = min(height[head], height[tail]);
		int x = tail - head;
		int temp = x * y;
		maxValue = max(maxValue, temp);
		/* 指针移动规则:移动高度低的指针
		 * 无论移动哪个指针x值都会缩小,高度低的指针限制了面积的大小
		 * 若移动高度低的指针:min(height[head], height[tail])可能变大,面积可能增大
		 * 若移动高度高的指针:min(height[head], height[tail])只会不变或变小,面积一定缩小
		 */

		if (height[head] < height[tail])
			head++;
		else
			tail--;
	}
	return maxValue;
}

/* 最长公共前缀 */
string Solution::longestCommonPrefix(vector<string>& strs) {
	if (strs.empty())
		return "";
	if (1 == strs.size())
		return strs[0];
	string ans = "";
	bool flag = true;
	for (int i = 0; i < strs[0].length() && flag; ++i)
	{
		char temp = strs[0][i];
		int j;
		int count = 0;
		for (j = 1; j < strs.size(); ++j)
		{
			if (i >= strs[j].length() || strs[j][i] != temp)
			{
				flag = false;
				break;
			}
			if (strs[j][i] == temp)
				count++;
		}
		if (strs.size() - 1 == count)
			ans += temp;
	}
	return ans;
}

/* 思路过程见 https://blog.csdn.net/qq_43069546/article/details/86496075 */
vector<vector<int>> Solution::threeSum(vector<int>& nums) {
	if (nums.size() < 3)
		return {};
	vector<vector<int>> ans;
	sort(nums.begin(), nums.end());
	for (int l = 0; l < nums.size(); ++l)
	{
		if (l > 0 && nums[l] == nums[l - 1])
			continue;
		int m = l + 1, r = nums.size() - 1;
		while (m < r)
		{
			int sum = nums[l] + nums[m] + nums[r];
			if (sum > 0)
				r--;
			else if (sum < 0)
				m++;
			else
			{
				ans.push_back({ nums[r],nums[l],nums[m] });
				m++;
				while (m < r&&nums[m] == nums[m - 1])
					m++;
			}
		}
	}
	return ans;
}

/* 思路就是15题的双指针法,记录下最小的sum,加上target就是答案 */
int Solution::threeSumClosest(vector<int>& nums, int target) {
	if (nums.size() < 3)
		return 0;
	int ans = INT_MAX;
	sort(nums.begin(), nums.end());
	for (int l = 0; l < nums.size(); ++l)
	{
		if (l > 0 && nums[l] == nums[l - 1])
			continue;
		int m = l + 1, r = nums.size() - 1;
		while (m < r)
		{
			int sum = nums[l] + nums[m] + nums[r] - target;		/* 差值 */
			if (0 == sum)
				return target;
			else if (sum > 0)
			{
				ans = (abs(ans) < abs(sum)) ? ans : sum;
				r--;
			}
			else
			{
				ans = (abs(ans) < abs(sum)) ? ans : sum;
				m++;
			}
		}
	}
	return ans + target;
}

/* 模拟一个栈,符号匹配就相消,栈空则返回true */
bool Solution::isValid(string s) {
	if (s.empty())
		return true;
	if (0 != s.length() % 2)
		return false;
	vector<char> res;
	map<char, char> str;
	str['('] = ')';
	str['['] = ']';
	str['{'] = '}';
	res.push_back(s[0]);
	for (int i = 1; i < s.length(); ++i)
	{
		res.push_back(s[i]);
		int tail = res.size() - 1;
		if (tail>0&&str[res[tail-1]] == res[tail]) /* 匹配的符号相消 */
		{
			res.pop_back();
			res.pop_back();
		}
	}
	return res.empty();
}

/* 链表的尾端插入操作 */
ListNode* Solution::mergeTwoLists(ListNode* l1, ListNode* l2) {
	ListNode* head1 = l1;
	ListNode* head2 = l2;
	ListNode* ans=new ListNode(0);
	ListNode* head = ans;
	while (head1&&head2)
	{
		int a = head1->val,b=head2->val;
		if (a<b)
		{
			head->next = head1;
			head1 = head1->next;
		}
		else
		{
			head->next = head2;
			head2 = head2->next;
		}
		head = head->next;
	}
	if (head1)
		head->next= head1;
	if (head2)
		head->next = head2;
	return ans->next; /* 避开自己初始化的第一个节点 */
}

/* k个链表数据写在一个数组,然后将数组转为链表
 * 其实可以类似归并排序,具体见 https://blog.csdn.net/qq_43069546/article/details/86511844
 */
ListNode* Solution::mergeKLists(vector<ListNode*>& lists) {
	if (lists.empty())
		return nullptr;
	vector<int> temp;
	ListNode* ans = new ListNode(0);
	ListNode* p = ans;
	for (int i = 0; i < lists.size(); ++i)
	{
		ListNode* head = lists[i];
		while (head)
		{
			temp.push_back(head->val);
			head = head->next;
		}
	}
	sort(temp.begin(), temp.end());
	for (int i = 0; i < temp.size(); ++i)
	{
		ListNode* t = new ListNode(temp[i]);
		p->next = t;
		p = p->next;
	}
	return ans->next; /* 避开自己初始化的第一个节点 */
}

/* vector去重方法 */
int Solution::removeDuplicates(vector<int>& nums) {
	if (nums.size() < 2)
		return nums.size();
	nums.erase(unique(nums.begin(), nums.end()), nums.end());
	return nums.size();
}

/* 直接二分法,移动l、r,注意中间值左右必有一边是有序的 */
int Solution::search(vector<int>& nums, int target) {
	if ((nums.empty())||(1==nums.size()&&nums[0]!=target))
		return -1;
	int l = 0, r = nums.size() - 1;
	while (l <= r)
	{
		int mid = (r - l) / 2 + l;	/* 取中 */
		if (target == nums[mid])
			return mid;
		if (nums[mid] < nums[r])    /* 右边有序 */
		{
			if (nums[mid] < target&&target <= nums[r])
				l = mid + 1;
			else
				r = mid - 1;
		}
		else						/* 左边有序 */
		{
			if (nums[mid] > target&&target >= nums[l])
				r = mid - 1;
			else
				l = mid + 1;
		}
	}
	return -1;
}

/* 二分查找 */
int Solution::binarySearch(vector<int>& nums, int target) {
	int l = 0, r = nums.size() - 1;
	while (l <= r)
	{
		int mid = (r - l) / 2 + l;
		if (target == nums[mid]) return mid;
		else if (target > nums[mid]) l = mid + 1;
		else r = mid - 1;
	}
	return -1;
}

/* 字典序算法,四步完成,详见 https://blog.csdn.net/qq_43069546/article/details/86553779 */
vector<vector<int>> Solution::permute(vector<int>& nums) {
	if (nums.size() < 2)
		return { nums };
	vector<vector<int>> ans;
	int size = nums.size();
	bool loop = true;
	sort(nums.begin(), nums.end());	/* 从第一个序列开始 */
	ans.push_back(nums);
	for (int i = 1;loop; ++i)
	{
		int firstMin,firstMax,maxVal=INT_MAX;
		/* 1.自右至左找出排列中第一个比右边数字小的数字 */
		for (int j = size - 1; j >= 0; --j)
		{
			if (0 == j)   /* 已经达到了最后一个序列 */
			{
				loop = false;
				break;
			}
			if (nums[j - 1] < nums[j])
			{
				firstMin = j - 1;
				break;
			}
		}
		if (!loop)break;
		/* 2.找出此数字右边最小的比它大的数字 */
		for (int j = firstMin + 1; j < size; ++j)
		{
			if (nums[j] > nums[firstMin] && nums[j] < maxVal)
			{
				firstMax = j;
				maxVal = nums[j];
			}
		}
		/* 3.交换 */
		swap(nums[firstMax], nums[firstMin]);
		/* 4.反转 */
		int l = firstMin + 1, r = size-1;
		while (l < r)
		{
			swap(nums[l], nums[r]);
			l++; 
			r--;
		}
		ans.push_back(nums);
	}
	return ans;
}

/* 动态规划,sum<0就舍弃 */
int Solution::maxSubArray(vector<int>& nums) {
	int sum = 0, ans = INT_MIN;
	for (int i = 0; i < nums.size(); ++i)
	{
		if (sum > 0)sum += nums[i];
		else sum = nums[i];
		ans = max(ans, sum);
	}
	return ans;
}

/* 模拟法,正常操作应该创建一个bool矩阵记录状态,此处作弊使用INT_MIN */
vector<int> Solution::spiralOrder(vector<vector<int>>& matrix) {
	if (matrix.empty() || matrix[0].empty())
		return {};
	int row = matrix.size();
	int col = matrix[0].size();
	int x = 0, y = 0;
	vector<int> res;
	while(res.size()<row*col)
	{
		while(y < col&&matrix[x][y] != INT_MIN)	  /* 向右 */
		{
			res.push_back(matrix[x][y]);
			matrix[x][y] = INT_MIN;
			y++;
		}
		y--;
		x++;
		while (x < row&&matrix[x][y] != INT_MIN)	/* 向下 */
		{
			res.push_back(matrix[x][y]);
			matrix[x][y] = INT_MIN;
			x++;
		}
		x--;
		y--;
		while (y >= 0 && matrix[x][y] != INT_MIN)	/* 向左 */
		{
			res.push_back(matrix[x][y]);
			matrix[x][y] = INT_MIN;
			y--;
		}
		y++;
		x--;
		while (x >= 0 && matrix[x][y] != INT_MIN)	/* 向上 */
		{
			res.push_back(matrix[x][y]);
			matrix[x][y] = INT_MIN;
			x--;
		}
		x++;
		y++;
	}
	return res;
}

/* 模拟法,生成螺旋矩阵 */
vector<vector<int>> Solution::generateMatrix(int n) {
	if (n <= 0)
		return { {} };
	vector<vector<int>> ans;
	int size = 0;
	int x = 0, y = 0;
	for (int i = 0; i < n; ++i) /* 初始化ans */
	{
		ans.push_back({});
		for (int j = 0; j < n; ++j)
			ans[i].push_back(0);
	}
	while (size < n*n) /* 类似螺旋矩阵(遍历) */
	{
		while (y < n && 0 == ans[x][y])
		{
			size++;
			ans[x][y] = size;
			y++;
		}
		y--;
		x++;
		while (x < n && 0 == ans[x][y])
		{
			size++;
			ans[x][y] = size;
			x++;
		}
		x--;
		y--;
		while (y >= 0 && 0 == ans[x][y])
		{
			size++;
			ans[x][y] = size;
			y--;
		}
		y++;
		x--;
		while (x >= 0 && 0 == ans[x][y])
		{
			size++;
			ans[x][y] = size;
			x--;
		}
		x++;
		y++;
	}
	return ans;
}

/* 倒数第step个节点变成头节点 */
ListNode* Solution::rotateRight(ListNode* head, int k) {
	if (0 == k||nullptr==head||nullptr==head->next)
		return head;
	int size = 0;
	int step;
	ListNode* p = head;
	ListNode* pTail = head;
	ListNode* pHead = head;
	ListNode* ans = head;
	while (p)
	{
		if (p->next == nullptr)
			pTail = p;
		p = p->next;
		size++;
	}
	if (size < k)
	{
		step = k % size;
		if (0 == step)	return head;
	}
	else if (size == k)
		return head;
	else
		step = k;
	int pToRotate = size - step + 1;/* 第pToRotate个节点做头节点 */
	pToRotate-=2;
	p = head;
	while (pToRotate > 0)
	{
		p = p->next;
		pToRotate--;
	}
	ans = p->next;
	pTail->next = pHead;  /* 注意先成环再断开 */
	p->next = nullptr;
	return ans;
}
/* 计算组合数C,下标是m+n-2,上标是n-1或m-1 */
int Solution::uniquePaths(int m, int n) {
	if (m < 1 || n < 1)	return 0;
	if (1 == m || 1 == n) return 1;
	int64_t steps = m + n - 2;
	int x = min(m-1, n-1);
	int64_t f1 = 1,f2=1;
	for (int i = 0; i < x; ++i,steps--)
		f1 *= steps;
	for (int64_t i = 1; i <= x; ++i)
		f2 *= i;
	return f1 / f2;  /* 一直用int64_t,不要转成int */
}

/* 动态规划:f(n)=f(n-1)+f(n-2) 
 * 第 i 阶可以由以下两种方法得到:
 * 在第 (i-1)阶后向上爬一阶。
 * 在第 (i-2) 阶后向上爬 2 阶。
 * 所以到达第 i 阶的方法总数就是到第 (i-1)阶和第 (i-2) 阶的方法数之和。
 * 其他解法详见 https://leetcode-cn.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode/
 */
int Solution::climbStairs(int n) {
	if (n < 4)	return n;
	int* dp = new int[n + 1];
	dp[1] = 1;
	dp[2] = 2;
	for (int i = 3; i <= n; ++i)
		dp[i] = dp[i - 1] + dp[i - 2];
	return dp[n];
}

/* 斐波那契公式的时间复杂度:O(log(n)),pow 方法将会用去 log(n) 的时间 */
int Solution::climbStairsWithFibonacci(int n) {
	if (n < 4) return n;
	double f1 = (1 + sqrt(5)) / 2;
	double f2 = (1 - sqrt(5)) / 2;
	return (pow(f1, n + 1) - pow(f2, n + 1)) / sqrt(5);
}

/* 镜面反射法
 * 每次遍历一个nums[i],ans每次增加的元素即为:
 * ans之前所有元素每个加上个nums[i]
 * nums[i]
 */
vector<vector<int>> Solution::subsets(vector<int>& nums) {
	vector<vector<int>> ans;
	for (int i = 0; i < nums.size(); ++i)
	{
		vector<int> temp = { nums[i] };
		int size = ans.size();
		for (int j = 0; j <size; ++j)
		{
			vector<int> f = ans[j];
			f.push_back(nums[i]);
			ans.push_back(f);
		}
		ans.push_back(temp);
	}
	ans.push_back({});
	return ans;
}

/* 可以用镜面反射法,但是不如位运算直接
 * 格雷码生成:G(i) = i^(i/2).
 */
vector<int> Solution::grayCode(int n) {
	if (0 == n) return { 0 };
	vector<int> ans;
	for (int i = 0; i < 1 << n; ++i)
		ans.push_back(i ^ (i / 2));
	return ans;
}

/* 深度优先遍历 */
int Solution::maxDepth(TreeNode* root) {
	if (nullptr == root)return 0;
	return max(maxDepth(root->left) ,maxDepth(root->right)) + 1;
}

/* 转换成最大子序和问题。同53.题 
 * 其实subSum可以优化掉,见下面函数
 */
int Solution::maxProfit(vector<int>& prices) {
	if (prices.size() < 2) return 0;
	vector<int> subSum;
	int ans = INT_MIN, sum = 0;
	for (int i = 1; i < prices.size(); ++i)
		subSum.push_back(prices[i] - prices[i - 1]);
	for (int i = 0; i < subSum.size(); ++i)
	{
		if (sum > 0)
			sum += subSum[i];
		else
			sum = subSum[i];
		ans = max(ans, sum);
	}
	return max(ans, 0);
}

/* prices[i] - prices[i - 1]可看做收入子序
 * 收入子序里只选择正数加到sum就可以 
 */
int Solution::maxProfit2(vector<int>& prices) {
	if (prices.size() < 2) return 0;
	int sum=0;
	for (int i = 1; i < prices.size(); ++i)
		if (prices[i] - prices[i - 1] > 0)
			sum += (prices[i] - prices[i - 1]);
	return sum;
}

int main()
{
	char s[100];
    _itoa_s(161,s,100, 16);
	cout << s;
	system("pause");
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值