mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 00:43:04 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@ -263,6 +263,32 @@ public:
|
||||
## Java
|
||||
|
||||
```java
|
||||
// 双指针 中心扩散法
|
||||
class Solution {
|
||||
public String longestPalindrome(String s) {
|
||||
String s1 = "";
|
||||
String s2 = "";
|
||||
String res = "";
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
// 分两种情况:即一个元素作为中心点,两个元素作为中心点
|
||||
s1 = extend(s, i, i); // 情况1
|
||||
res = s1.length() > res.length() ? s1 : res;
|
||||
s2 = extend(s, i, i + 1); // 情况2
|
||||
res = s2.length() > res.length() ? s2 : res;
|
||||
}
|
||||
return res; // 返回最长的
|
||||
}
|
||||
public String extend(String s, int start, int end){
|
||||
String tmp = "";
|
||||
while (start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)){
|
||||
tmp = s.substring(start, end + 1); // Java中substring是左闭右开的,所以要+1
|
||||
// 向两边扩散
|
||||
start--;
|
||||
end++;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
@ -317,6 +343,7 @@ class Solution:
|
||||
## Go
|
||||
|
||||
```go
|
||||
|
||||
```
|
||||
|
||||
## JavaScript
|
||||
|
@ -118,7 +118,7 @@ next数组就是一个前缀表(prefix table)。
|
||||
|
||||
此时就要问了**前缀表是如何记录的呢?**
|
||||
|
||||
首先要知道前缀表的任务是当前位置匹配失败,找到之前已经匹配上的位置,在重新匹配,此也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。
|
||||
首先要知道前缀表的任务是当前位置匹配失败,找到之前已经匹配上的位置,再重新匹配,此也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。
|
||||
|
||||
那么什么是前缀表:**记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。**
|
||||
|
||||
@ -146,7 +146,7 @@ next数组就是一个前缀表(prefix table)。
|
||||
|
||||
# 为什么一定要用前缀表
|
||||
|
||||
这就是前缀表那为啥就能告诉我们 上次匹配的位置,并跳过去呢?
|
||||
这就是前缀表,那为啥就能告诉我们 上次匹配的位置,并跳过去呢?
|
||||
|
||||
回顾一下,刚刚匹配的过程在下标5的地方遇到不匹配,模式串是指向f,如图:
|
||||
<img src='https://code-thinking.cdn.bcebos.com/pics/KMP%E7%B2%BE%E8%AE%B21.png' width=600 alt='KMP精讲1'> </img></div>
|
||||
|
@ -163,6 +163,29 @@ class Solution:
|
||||
low += 1
|
||||
high -= 1
|
||||
```
|
||||
>上一版本简化版
|
||||
'''python
|
||||
class Solution(object):
|
||||
def nextPermutation(self, nums: List[int]) -> None:
|
||||
n = len(nums)
|
||||
i = n-2
|
||||
while i >= 0 and nums[i] >= nums[i+1]:
|
||||
i -= 1
|
||||
|
||||
if i > -1: // i==-1,不存在下一个更大的排列
|
||||
j = n-1
|
||||
while j >= 0 and nums[j] <= nums[i]:
|
||||
j -= 1
|
||||
nums[i], nums[j] = nums[j], nums[i]
|
||||
|
||||
start, end = i+1, n-1
|
||||
while start < end:
|
||||
nums[start], nums[end] = nums[end], nums[start]
|
||||
start += 1
|
||||
end -= 1
|
||||
|
||||
return nums
|
||||
'''
|
||||
|
||||
## Go
|
||||
|
||||
|
@ -602,7 +602,48 @@ func trap(height []int) int {
|
||||
}
|
||||
```
|
||||
|
||||
动态规划解法:
|
||||
|
||||
```go
|
||||
func trap(height []int) int {
|
||||
sum:=0
|
||||
n:=len(height)
|
||||
lh:=make([]int,n)
|
||||
rh:=make([]int,n)
|
||||
lh[0]=height[0]
|
||||
rh[n-1]=height[n-1]
|
||||
for i:=1;i<n;i++{
|
||||
lh[i]=max(lh[i-1],height[i])
|
||||
}
|
||||
for i:=n-2;i>=0;i--{
|
||||
rh[i]=max(rh[i+1],height[i])
|
||||
}
|
||||
for i:=1;i<n-1;i++{
|
||||
h:=min(rh[i],lh[i])-height[i]
|
||||
if h>0{
|
||||
sum+=h
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
func max(a,b int)int{
|
||||
if a>b{
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
func min(a,b int)int{
|
||||
if a<b{
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
JavaScript:
|
||||
|
||||
```javascript
|
||||
//双指针
|
||||
var trap = function(height) {
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
那么排列问题其实也是一样的套路。
|
||||
|
||||
**还要强调的是去重一定要对元素经行排序,这样我们才方便通过相邻的节点来判断是否重复使用了**。
|
||||
**还要强调的是去重一定要对元素进行排序,这样我们才方便通过相邻的节点来判断是否重复使用了**。
|
||||
|
||||
我以示例中的 [1,1,2]为例 (为了方便举例,已经排序)抽象为一棵树,去重过程如图:
|
||||
|
||||
|
@ -598,5 +598,60 @@ var maxDepth = function(root) {
|
||||
};
|
||||
```
|
||||
|
||||
## C
|
||||
二叉树最大深度递归
|
||||
```c
|
||||
int maxDepth(struct TreeNode* root){
|
||||
//若传入结点为NULL,返回0
|
||||
if(!root)
|
||||
return 0;
|
||||
|
||||
//求出左子树深度
|
||||
int left = maxDepth(root->left);
|
||||
//求出右子树深度
|
||||
int right = maxDepth(root->right);
|
||||
//求出左子树深度和右子树深度的较大值
|
||||
int max = left > right ? left : right;
|
||||
//返回较大值+1(1为当前层数)
|
||||
return max + 1;
|
||||
}
|
||||
```
|
||||
二叉树最大深度迭代
|
||||
```c
|
||||
int maxDepth(struct TreeNode* root){
|
||||
//若传入根节点为NULL,返回0
|
||||
if(!root)
|
||||
return 0;
|
||||
|
||||
int depth = 0;
|
||||
//开辟队列空间
|
||||
struct TreeNode** queue = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 6000);
|
||||
int queueFront = 0;
|
||||
int queueEnd = 0;
|
||||
|
||||
//将根结点入队
|
||||
queue[queueEnd++] = root;
|
||||
|
||||
int queueSize;
|
||||
//求出当前队列中元素个数
|
||||
while(queueSize = queueEnd - queueFront) {
|
||||
int i;
|
||||
//若当前队列中结点有左右子树,则将它们的左右子树入队
|
||||
for(i = 0; i < queueSize; i++) {
|
||||
struct TreeNode* tempNode = queue[queueFront + i];
|
||||
if(tempNode->left)
|
||||
queue[queueEnd++] = tempNode->left;
|
||||
if(tempNode->right)
|
||||
queue[queueEnd++] = tempNode->right;
|
||||
}
|
||||
//更新队头下标
|
||||
queueFront += queueSize;
|
||||
//深度+1
|
||||
depth++;
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -197,6 +197,33 @@ class Solution:
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
// 买卖股票的最佳时机Ⅱ 动态规划
|
||||
// 时间复杂度O(n) 空间复杂度O(n)
|
||||
func maxProfit(prices []int) int {
|
||||
dp := make([][]int, len(prices))
|
||||
status := make([]int, len(prices) * 2)
|
||||
for i := range dp {
|
||||
dp[i] = status[:2]
|
||||
status = status[2:]
|
||||
}
|
||||
dp[0][0] = -prices[0]
|
||||
|
||||
for i := 1; i < len(prices); i++ {
|
||||
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i])
|
||||
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i])
|
||||
}
|
||||
|
||||
return dp[len(prices) - 1][1]
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
func maxProfit(prices []int) int {
|
||||
|
@ -347,7 +347,38 @@ const maxProfit = prices => {
|
||||
};
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
> 版本一:
|
||||
```go
|
||||
// 买卖股票的最佳时机III 动态规划
|
||||
// 时间复杂度O(n) 空间复杂度O(n)
|
||||
func maxProfit(prices []int) int {
|
||||
dp := make([][]int, len(prices))
|
||||
status := make([]int, len(prices) * 4)
|
||||
for i := range dp {
|
||||
dp[i] = status[:4]
|
||||
status = status[4:]
|
||||
}
|
||||
dp[0][0], dp[0][2] = -prices[0], -prices[0]
|
||||
|
||||
for i := 1; i < len(prices); i++ {
|
||||
dp[i][0] = max(dp[i - 1][0], -prices[i])
|
||||
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i])
|
||||
dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] - prices[i])
|
||||
dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] + prices[i])
|
||||
}
|
||||
|
||||
return dp[len(prices) - 1][3]
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -273,6 +273,41 @@ class Solution:
|
||||
return dp[2*k]
|
||||
```
|
||||
Go:
|
||||
版本一:
|
||||
```go
|
||||
// 买卖股票的最佳时机IV 动态规划
|
||||
// 时间复杂度O(kn) 空间复杂度O(kn)
|
||||
func maxProfit(k int, prices []int) int {
|
||||
if k == 0 || len(prices) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
dp := make([][]int, len(prices))
|
||||
status := make([]int, (2 * k + 1) * len(prices))
|
||||
for i := range dp {
|
||||
dp[i] = status[:2 * k + 1]
|
||||
status = status[2 * k + 1:]
|
||||
}
|
||||
for j := 1; j < 2 * k; j += 2 {
|
||||
dp[0][j] = -prices[0]
|
||||
}
|
||||
|
||||
for i := 1; i < len(prices); i++ {
|
||||
for j := 0; j < 2 * k; j += 2 {
|
||||
dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i])
|
||||
dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i])
|
||||
}
|
||||
}
|
||||
return dp[len(prices) - 1][2 * k]
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
func maxProfit(k int, prices []int) int {
|
||||
|
@ -447,7 +447,80 @@ var countNodes = function(root) {
|
||||
};
|
||||
```
|
||||
|
||||
## C:
|
||||
递归法
|
||||
```c
|
||||
int countNodes(struct TreeNode* root) {
|
||||
//若传入结点不存在,返回0
|
||||
if(!root)
|
||||
return 0;
|
||||
//算出左右子树的结点总数
|
||||
int leftCount = countNodes(root->left);
|
||||
int rightCount = countNodes(root->right);
|
||||
//返回左右子树结点总数+1
|
||||
return leftCount + rightCount + 1;
|
||||
}
|
||||
|
||||
int countNodes(struct TreeNode* root){
|
||||
return getNodes(root);
|
||||
}
|
||||
```
|
||||
|
||||
迭代法
|
||||
```c
|
||||
int countNodes(struct TreeNode* root){
|
||||
//记录结点总数
|
||||
int totalNum = 0;
|
||||
//开辟栈空间
|
||||
struct TreeNode** stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 100);
|
||||
int stackTop = 0;
|
||||
//如果root结点不为NULL,则将其入栈。若为NULL,则不会进入遍历,返回0
|
||||
if(root)
|
||||
stack[stackTop++] = root;
|
||||
//若栈中有结点存在,则进行遍历
|
||||
while(stackTop) {
|
||||
//取出栈顶元素
|
||||
struct TreeNode* tempNode = stack[--stackTop];
|
||||
//结点总数+1
|
||||
totalNum++;
|
||||
//若栈顶结点有左右孩子,将它们入栈
|
||||
if(tempNode->left)
|
||||
stack[stackTop++] = tempNode->left;
|
||||
if(tempNode->right)
|
||||
stack[stackTop++] = tempNode->right;
|
||||
}
|
||||
return totalNum;
|
||||
}
|
||||
```
|
||||
|
||||
满二叉树
|
||||
```c
|
||||
int countNodes(struct TreeNode* root){
|
||||
if(!root)
|
||||
return 0;
|
||||
int leftHeight = 0;
|
||||
int rightHeight = 0;
|
||||
struct TreeNode* rightNode = root->right;
|
||||
struct TreeNode* leftNode = root->left;
|
||||
//求出左子树深度
|
||||
while(leftNode) {
|
||||
leftNode = leftNode->left;
|
||||
leftHeight++;
|
||||
}
|
||||
|
||||
//求出右子树深度
|
||||
while(rightNode) {
|
||||
rightNode = rightNode->right;
|
||||
rightHeight++;
|
||||
}
|
||||
//若左右子树深度相同,为满二叉树。结点个数为2^height-1
|
||||
if(rightHeight == leftHeight) {
|
||||
return (2 << leftHeight) - 1;
|
||||
}
|
||||
//否则返回左右子树的结点个数+1
|
||||
return countNodes(root->right) + countNodes(root->left) + 1;
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -563,7 +563,7 @@ var invertTree = function(root) {
|
||||
};
|
||||
```
|
||||
|
||||
C:
|
||||
### C:
|
||||
递归法
|
||||
```c
|
||||
struct TreeNode* invertTree(struct TreeNode* root){
|
||||
@ -580,6 +580,7 @@ struct TreeNode* invertTree(struct TreeNode* root){
|
||||
return root;
|
||||
}
|
||||
```
|
||||
|
||||
迭代法:深度优先遍历
|
||||
```c
|
||||
struct TreeNode* invertTree(struct TreeNode* root){
|
||||
|
@ -408,7 +408,7 @@ var maxSlidingWindow = function (nums, k) {
|
||||
// 入队当前元素下标
|
||||
q.push(i);
|
||||
// 判断当前最大值(即队首元素)是否在窗口中,若不在便将其出队
|
||||
while (q[0] <= i - k) {
|
||||
if (q[0] <= i - k) {
|
||||
q.shift();
|
||||
}
|
||||
// 当达到窗口大小时便开始向结果中添加数据
|
||||
|
@ -205,6 +205,40 @@ class Solution:
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
// 最佳买卖股票时机含冷冻期 动态规划
|
||||
// 时间复杂度O(n) 空间复杂度O(n)
|
||||
func maxProfit(prices []int) int {
|
||||
n := len(prices)
|
||||
if n < 2 {
|
||||
return 0
|
||||
}
|
||||
|
||||
dp := make([][]int, n)
|
||||
status := make([]int, n * 4)
|
||||
for i := range dp {
|
||||
dp[i] = status[:4]
|
||||
status = status[4:]
|
||||
}
|
||||
dp[0][0] = -prices[0]
|
||||
|
||||
for i := 1; i < n; i++ {
|
||||
dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1] - prices[i], dp[i - 1][3] - prices[i]))
|
||||
dp[i][1] = max(dp[i - 1][1], dp[i - 1][3])
|
||||
dp[i][2] = dp[i - 1][0] + prices[i]
|
||||
dp[i][3] = dp[i - 1][2]
|
||||
}
|
||||
|
||||
return max(dp[n - 1][1], max(dp[n - 1][2], dp[n - 1][3]))
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
|
||||
|
@ -121,6 +121,41 @@ class Solution {
|
||||
```
|
||||
|
||||
Python:
|
||||
### 解法1:
|
||||
扫描每个cell,如果当前位置为岛屿 grid[i][j] == 1, 从当前位置判断四边方向,如果边界或者是水域,证明有边界存在,res矩阵的对应cell加一。
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def islandPerimeter(self, grid: List[List[int]]) -> int:
|
||||
|
||||
m = len(grid)
|
||||
n = len(grid[0])
|
||||
|
||||
# 创建res二维素组记录答案
|
||||
res = [[0] * n for j in range(m)]
|
||||
|
||||
for i in range(m):
|
||||
for j in range(len(grid[i])):
|
||||
# 如果当前位置为水域,不做修改或reset res[i][j] = 0
|
||||
if grid[i][j] == 0:
|
||||
res[i][j] = 0
|
||||
# 如果当前位置为陆地,往四个方向判断,update res[i][j]
|
||||
elif grid[i][j] == 1:
|
||||
if i == 0 or (i > 0 and grid[i-1][j] == 0):
|
||||
res[i][j] += 1
|
||||
if j == 0 or (j >0 and grid[i][j-1] == 0):
|
||||
res[i][j] += 1
|
||||
if i == m-1 or (i < m-1 and grid[i+1][j] == 0):
|
||||
res[i][j] += 1
|
||||
if j == n-1 or (j < n-1 and grid[i][j+1] == 0):
|
||||
res[i][j] += 1
|
||||
|
||||
# 最后求和res矩阵,这里其实不一定需要矩阵记录,可以设置一个variable res 记录边长,舍矩阵无非是更加形象而已
|
||||
ans = sum([sum(row) for row in res])
|
||||
|
||||
return ans
|
||||
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
@ -354,6 +354,35 @@ var constructMaximumBinaryTree = function (nums) {
|
||||
};
|
||||
```
|
||||
|
||||
## C
|
||||
```c
|
||||
struct TreeNode* traversal(int* nums, int left, int right) {
|
||||
//若左边界大于右边界,返回NULL
|
||||
if(left >= right)
|
||||
return NULL;
|
||||
|
||||
//找出数组中最大数坐标
|
||||
int maxIndex = left;
|
||||
int i;
|
||||
for(i = left + 1; i < right; i++) {
|
||||
if(nums[i] > nums[maxIndex])
|
||||
maxIndex = i;
|
||||
}
|
||||
|
||||
//开辟结点
|
||||
struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
|
||||
//将结点的值设为最大数组数组元素
|
||||
node->val = nums[maxIndex];
|
||||
//递归定义左孩子结点和右孩子结点
|
||||
node->left = traversal(nums, left, maxIndex);
|
||||
node->right = traversal(nums, maxIndex + 1, right);
|
||||
return node;
|
||||
}
|
||||
|
||||
struct TreeNode* constructMaximumBinaryTree(int* nums, int numsSize){
|
||||
return traversal(nums, 0, numsSize);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -139,7 +139,7 @@ if (root->val < low) {
|
||||
root->left = trimBST(root->left, low, high);
|
||||
```
|
||||
|
||||
此时节点3的右孩子就变成了节点2,将节点0从二叉树中移除了。
|
||||
此时节点3的左孩子就变成了节点2,将节点0从二叉树中移除了。
|
||||
|
||||
最后整体代码如下:
|
||||
|
||||
|
@ -150,14 +150,16 @@ class Solution:
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
```go
|
||||
// 买卖股票的最佳时机含手续费 动态规划
|
||||
// 时间复杂度O(n) 空间复杂度O(n)
|
||||
func maxProfit(prices []int, fee int) int {
|
||||
n := len(prices)
|
||||
dp := make([][2]int, n)
|
||||
dp[0][0] = -prices[0]
|
||||
for i := 1; i < n; i++ {
|
||||
dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i]-fee)
|
||||
dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i])
|
||||
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i] - fee)
|
||||
dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i])
|
||||
}
|
||||
return dp[n-1][1]
|
||||
}
|
||||
|
@ -267,6 +267,57 @@ var removeDuplicates = function(s) {
|
||||
};
|
||||
```
|
||||
|
||||
C:
|
||||
方法一:使用栈
|
||||
```c
|
||||
char * removeDuplicates(char * s){
|
||||
//求出字符串长度
|
||||
int strLength = strlen(s);
|
||||
//开辟栈空间。栈空间长度应为字符串长度+1(为了存放字符串结束标志'\0')
|
||||
char* stack = (char*)malloc(sizeof(char) * strLength + 1);
|
||||
int stackTop = 0;
|
||||
|
||||
int index = 0;
|
||||
//遍历整个字符串
|
||||
while(index < strLength) {
|
||||
//取出当前index对应字母,之后index+1
|
||||
char letter = s[index++];
|
||||
//若栈中有元素,且栈顶字母等于当前字母(两字母相邻)。将栈顶元素弹出
|
||||
if(stackTop > 0 && letter == stack[stackTop - 1])
|
||||
stackTop--;
|
||||
//否则将字母入栈
|
||||
else
|
||||
stack[stackTop++] = letter;
|
||||
}
|
||||
//存放字符串结束标志'\0'
|
||||
stack[stackTop] = '\0';
|
||||
//返回栈本身作为字符串
|
||||
return stack;
|
||||
}
|
||||
```
|
||||
方法二:双指针法
|
||||
```c
|
||||
char * removeDuplicates(char * s){
|
||||
//创建快慢指针
|
||||
int fast = 0;
|
||||
int slow = 0;
|
||||
//求出字符串长度
|
||||
int strLength = strlen(s);
|
||||
//遍历字符串
|
||||
while(fast < strLength) {
|
||||
//将当前slow指向字符改为fast指向字符。fast指针+1
|
||||
char letter = s[slow] = s[fast++];
|
||||
//若慢指针大于0,且慢指针指向元素等于字符串中前一位元素,删除慢指针指向当前元素
|
||||
if(slow > 0 && letter == s[slow - 1])
|
||||
slow--;
|
||||
else
|
||||
slow++;
|
||||
}
|
||||
//在字符串结束加入字符串结束标志'\0'
|
||||
s[slow] = 0;
|
||||
return s;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -150,7 +150,35 @@ class Solution:
|
||||
res[i] = hash[num]
|
||||
return res
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
func smallerNumbersThanCurrent(nums []int) []int {
|
||||
// map,key[数组中出现的数] value[比这个数小的个数]
|
||||
m := make(map[int]int)
|
||||
// 拷贝一份原始数组
|
||||
rawNums := make([]int,len(nums))
|
||||
copy(rawNums,nums)
|
||||
// 将数组排序
|
||||
sort.Ints(nums)
|
||||
// 循环遍历排序后的数组,值为map的key,索引为value
|
||||
for i,v := range nums {
|
||||
_,contains := m[v]
|
||||
if !contains {
|
||||
m[v] = i
|
||||
}
|
||||
|
||||
}
|
||||
// 返回值结果
|
||||
result := make([]int,len(nums))
|
||||
// 根据原始数组的位置,存放对应的比它小的数
|
||||
for i,v := range rawNums {
|
||||
result[i] = m[v]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
```
|
||||
|
||||
JavaScript:
|
||||
```javascript
|
||||
|
Reference in New Issue
Block a user