做网站需要学数据库吗,响应式布局网站,做系统去哪个网站好,帮人家做网站维护回文数
反转一半数字 第一个想法是将数字转换为字符串#xff0c;并检查字符串是否为回文。 但是#xff0c;这需要额外的非常量空间来创建问题描述中所不允许的字符串。
第二个想法是将数字本身反转#xff0c;然后将反转的数字与原始数字比较#xff0c;如果它们是相同…回文数
反转一半数字 第一个想法是将数字转换为字符串并检查字符串是否为回文。 但是这需要额外的非常量空间来创建问题描述中所不允许的字符串。
第二个想法是将数字本身反转然后将反转的数字与原始数字比较如果它们是相同的那么这个数字就是回文。 但是如果反转后的数字大于int.MAX我们将遇到整数溢出问题。
反转int数字的一半如果该数字是回文反转后半部分应与原始数字的前半部分相同。
例如输入 1221我们可以将数字 “1221” 的后半部分从 “21” 反转为 “12”并将其与前半部分 “12” 进行比较因为二者相同我们得知数字 1221 是回文。
首先我们应该处理一些临界情况。所有负数都不可能是回文例如-123 不是回文因为 - 不等于 3。所以我们可以对所有负数返回 false。除了 0 以外所有个位是 0 的数字不可能是回文因为最高位不等于 0。所以我们可以对所有大于 0 且个位是 0 的数字返回 false。
整个过程中不断将原始数字除以10然后给反转的数字乘上10当原始数字小于或等于反转后的数字时就意味着已经处理了一半位数的数字了。
最长公共前缀
显然最长公共前缀的长度不会超过字符串数组中的最短字符串的长度。 用minLength表示字符串数组中的最短字符串的长度则可以在[o, minLength]范围内通过二分查找得到最长公共前缀的长度。 每次查找返回的中间值mid判断每个字符串的长度为mid的前缀是否相同如果相同则最长公共前缀的长度一定大于或等于mid如果不相同则小于mid。
移除链表元素
给一个链表的头节点head和一个整数val请删除链表中所有满足Node.valval的节点并返回新的头节点。 递归 链表的定义具有递归的性质因此链表题目常可以用递归的方法求解。
对于给定的链表首先对除了头节点head以外的节点进行删除操作然后判断。
递归的终止条件是head为空此时直接返回head。 当head不为空时递归地进行删除操作然后判断 head 的节点值是否等于 val并决定是否要删除 head。
同构字符串
哈希表 需要判断s和t每个位置上的字符是否都一一对应即s的任意一个字符被t中唯一的字符对应反之也成立称为双射。
因此维护两张哈希表第一张哈希表以s中字符为键t中字符为值。
爬楼梯
假设你正在爬楼梯需要n阶才能到达楼顶 每次可以爬1或2个台阶有多少种不同方法可以爬楼梯
用f(x)表示爬到第x级台阶的方案数最后一步可能跨了一级台阶也可能跨了两级台阶所以可以列出如下式子
f(x) f(x-1) f(x-2)买卖股票的最佳时机二
不能同时参与多笔交易因此每天交易结束后只可能存在手里有一只股票或者没有股票的状态。
定义状态dp[i][0]表示第i天交易完后手里没有股票的最大利润dp[i][1]表示第i天交易完后手里持有一支股票的最大利润i从0开始。
dp[i][0]的转移方程如果这一天交易完后手里没有股票那么可能前一天也没有或者前一天的时候有
dp[i][0] max{dp[i-1][0], dp[i-1][1]prices[i]}dp[i][1]可能前一天就有这个股票可能前一天没有然后买下了股票
dp[i][1] max{dp[i-1][1], dp[i-1][0]-prices[i]}对于初始状态根据状态定义
dp[0][0] 0;
dp[0][1] -prices[0];因此只需要从前往后计算即可。 由于全部交易结束后持有股票的收益一定低于不持有股票的收益 所以的最后答案一定为dp[n-1][0]
使用最小花费爬楼梯
给一个整数数组cost[i]是从楼梯第i个台阶向上爬需要的费用一旦支付此费用可以向上爬一个或者两个台阶。
可以从下标0或1开始爬求最低花费。
动态规划 假设数组cost的长度为n则n个阶梯分别对应下标0到n-1楼梯顶部对应下标n问题等价于计算达到下标n的最小划分。
创建长度为n1的数组dp其中dp[i]表示达到下标i的最小花费。 dp[0] dp[1] 0;
dp[i] min{dp[i-1]cost[i-1],dp[i-2]cost[i-2]}构造限制重复的字符串
给一个字符串s和一个整数repeatLimit用s中的字符构造一个新字符使任何字母连续出现的次数都不超过repeatLimit次。
每次选择当前剩余的字典序最大的字符添加到字符串末尾如果字符串末尾的字符已经连续出现了repeatLimit次则将字典序次大的字符添加到末尾随后选择当前剩余字典序最大的字符添加到末尾直到使用完。
用下标i指向当前未使用的字典序最大的字符用下标j指向当前未使用的字典序的次大的字符满足count[j]0以及ji用m记录当前已经填入的末尾字符的连续次数。
拿出最少数目的魔法豆
给定一个正整数数组beans其中每个整数表示一个袋子里装的魔法豆的数目。 可将问题转化为寻找某一个数字x当我们将豆子数量小于x的袋子清空并将豆子数量大于x的袋中豆子数量变为x时拿出的豆子数量最少。
那么x一定等于某一个袋子的豆子数。
跳跃游戏
nums[i]表示从i向前跳转的最大长度返回到达nums[n-1]的最小跳跃次数。
这道题典型是贪心算法通过局部最优解得到全局最优解
反向查找出发位置 目标是到达最后一个位置因此可以考虑跳跃最后一步之前所在的位置。
如果有多个位置都能通过跳跃到达最后一个位置那么可以贪心地选择距离最后一个位置最远的位置。
正向查找可到达的最大位置 如果贪心地进行正向查找每次找到可到达的最远位置就可以在线性时间内得到最少跳跃次数。
在具体实现中我们维护能够到达的最大下标位置称为边界。到达边界时更新边界并将跳跃次数增加1。
盛最多水的容器
双指针 在初始时左右指针分别指向数组的左右两端它们可以容纳的水量为min(1,7)*8 8。
此时需要移动哪个指针呢应该移动数字较小的那个指针这是因为容纳的水量是由两个指针指向的较小值*指针之间的距离。
双指针代表的是可以作为容器边界的所有位置的范围。在一开始双指针指向数组的左右边界表示数组中所有的位置都可以作为容器的边界因此还没有进行任何尝试。
在链表中插入最大公约数
给一个链表头head每个结点包含一个整数值。
在相邻结点之间插入一个新的结点节点值为这两个相邻结点值的最大公约数。
class Solution{
public:ListNode* insertGreatestCommonDivisors(ListNode* head) {ListNode* node head;while(node-next){node-next new ListNode(__gcd(node-val,node-next-val), node-next);node node-next-next;}return head;}
};删除排序链表中的重复元素
给定一个已排序的链表的头head删除所有重复元素使每个元素只出现一次返回已排序的链表。
删除排序链表中的重复元素二
我们只需要对链表进行一次遍历就可以删除重复的元素。 由于链表的头节点可能会被删除因此我们需要额外使用一个哑结点dummy node指向链表的头节点。
从指针cur指向链表的哑结点然后遍历
故障键盘
笔记本键盘存在故障当上面输入字符’i’时会反转之前所写的字符。
使用双端队列进行模拟 比较直观的思路是维护答案字符串ans当遇到非i字符时就将其加入字符串的末尾否则将字符串进行反转。
然而字符串翻转需要O(l)的时间其中l是当前ans的长度这样做的时间复杂度较高。
事实上当字符串进行反转后在末尾添加字符相当于不对字符串进行反转并且在开头添加字符因此维护一个双端队列和一个布尔变量head来维护答案。
head初始值为假
当遇到非i字符时head为假时直接添加到末尾head为真时添加到队头。遇到i时head取反。
如果head为真就将队列中的字符反序构造。
找出克隆二叉树中的相同节点
给两棵二叉树原始树orginal和克隆树cloned以及一个位于原始树的target节点找到克隆树对应的节点。
深度优先搜索
/*** 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* getTargetCopy(TreeNode* original, TreeNode* cloned, TreeNode* target) {if(original nullptr){return nullptr;}if(original target){return cloned;}TreeNode* left getTargetCopy(original-left, cloned-left, target);if(left ! nullptr){return left;}return getTargetCopy(original-right, cloned-right, target);}
};广度优先搜索 使用队列同时对二叉树original和cloned进行广度优先搜索初始时分别将根节点original和clone压入队列q1和q2。 假设当前搜索的节点分别为node1和node2将node1和node2分别弹出队列如果node1节点的引用等于target那么返回node2否则分别将node1和node2的非空子节点压入队列q1和q2。
/*** 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* getTargetCopy(TreeNode* original, TreeNode* cloned, TreeNode* target) {queueTreeNode * q1,q2;q1.push(original);q2.push(cloned);while(!q1.empty()){TreeNode *node1 q1.front();TreeNode *node2 q2.front();q1.pop();q2.pop();if(node1 target){return node2;}if(node1-left ! nullptr){q1.push(node1-left);q2.push(node2-left);}if(node1-right ! nullptr){q1.push(node1-right);q2.push(node2-right);}}return nullptr;}
};在带权树网络中统计可连接服务器对数目
给一颗无限带权树树中总共有n个节点表示n个服务器服务器从0到n-1编号。
如果两个服务器a,b和c满足以下条件那么我们称服务器a和b通过服务器c可连接
abc到a的距离是可以被整除c到b的距离可以被整除c到b的路径从c到a的路径没有公共边
count[i]表示通过服务器i可连接的服务器对的数目
丑数
class Solution{
public:bool isUgly(int n){if(n 0){return false;}vectorint factors {2, 3, 5};for(int factor:factors){while(n % factor 0){n / factor;}}return n 1;}
}丑数二
最小堆 初始化堆为空首先将最小的丑数1加入堆。 每次取出堆顶元素则x是堆中最小的丑数由于2x3x5x也是丑数因此将2x3x5x加入堆。
上述做法会导致堆中出现重复元素的情况。 为了避免使用哈希集合去重。
在排除重复元素的情况下第n次从最小堆中取出的元素就是第n个丑数。
class Solution {
public:int nthUglyNumber(int n) {vectorint factors {2, 3, 5};unordered_setlong seen;priority_queuelong, vectorlong, greaterlong heap;seen.insert(1L);heap.push(1L);int ugly 0;for(int i0; in; i){long curr heap.top();heap.pop();ugly (int)curr;for(int factor: factors){long next curr * factor;if(!seen.count(next)){seen.insert(next);heap.push(next);}}}return ugly;}
};合并两个有序数组
给两个非递减顺序排列的整数数组nums和nums另有两个整数m和n分别表示nums1和nums2中的元素数目。
直接合并排序 把数组nums放进数组nums1的尾部然后直接对整个数组进行排序。
移除元素