题目描述:给你一个一个数组,其中包含四个数字。然后返回用这四个数字返回表示时间最大的字符串。
class Solution:
def largestTimeFromDigits(self, A):
"""
:type A: List[int]
:rtype: str
"""
ans=-1
for h1,h2,m1,m2 in itertools.permutations(A):
hours=h1*10+h2
mins=m1*10+m2
time=hours*60+mins
if 0<=hours<24 and 0<=mins<60 and time>ans:
ans=time
return "{:02}:{:02}".format(divmod(ans,60)) if ans>=0 else ""
//C++部分需要使用STL库里的<algorithm>中的next_permutation函数,详情可以参照:
//http://www.cnblogs.com/eudiwffe/p/6260699.html
class Solution {
public:
string largestTimeFromDigits(vector<int>& A) {
//先对A进行排序
sort(A.begin(),A.end());
int ans=-1;
do{
ans=max(ans,isValid(A));
}while(next_permutations(A.begin,A.end()));
if(ans<0)return "";
char buf[10];
sprintf(buff,"%02d:%02d",t/60,t%60);
return buf;
}
int isValid(vecotr<int> &A){
int hours=A[0]*10+A[1];
int mins=A[2]*10+A[3];
if(hours<0||hours>=24) return -1;
if(mins<0||mins>=60) return -1;
return hours*60+mins;
}
};
题目大意:我们可以为二叉树 T 定义一个翻转操作,如下所示:选择任意节点,然后交换它的左子树和右子树。 只要经过一定次数的翻转操作后,能使 X 等于 Y,我们就称二叉树 X 翻转等价于二叉树 Y。 编写一个判断两个二叉树是否是翻转等价的函数。这些树由根节点 root1 和 root2 给出。
题目思路:思路比较简单,利用递归。就是只需判断两树根节点是否相同。如不同直接返回false。如果根节点相同,递归判断两树的左子树和右子树是否满足。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def flipEquiv(self, root1, root2):
"""
:type root1: TreeNode
:type root2: TreeNode
:rtype: bool
"""
if not root1 and not root2:
return True
if not root1 or not root2:
return False
if root1.val!=root2.val:
return False
//左子树与左子树比较
bool1=self.flipEquiv(root1.left,root2.left) and self.flipEquiv(root1.right,root2.right)
//左子树和右子树比较
bool2=self.flipEquiv(root1.left,root2.right) and self.flipEquiv(root1.right,root2.left)
return bool1 or bool2
题目描述:给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式.
IP地址是一个四段数,每段的的数为0-255,例如0.0.0.0或255.255.255.2但是不能有01这样的数出现。
思路:
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vecotr<string> res;
dfs(s,0,0,"",res);
return res;
}
//string 待重建IP的string
//start: 重建的开始位置
//index:已经重建好的部分数量(简单理解,已经打了几个点)
//path:重建好的string
void buildIP(string s,int start,int index,string path,vector<string> res){
if(start==s.size()&&index==4){
path.erase(ip.end()-1); //减去最后那个.
res.push_back(path);
}
if(s.size()-start>(4-step)*3) return; //剩余过多
if(s.size()-start<(4-step)) return;
int num=0;
for(int i=start,i<start+3;i++){
num=num*10+(s[i]-'0');
if(num<=255)
ip+=s[i];
buildIp(s,i+1,step+1,ip+'.',res);
}
if(num==0) break; //首位是0,跳出循环。
}
};
class Solution:
def restoreIpAddresses(self, s):
"""
:type s: str
:rtype: List[str]
"""
res=[]
self.dfs(s,0,"",res)
return res
def dfs(s,index,path,res):
if not s and index==4:
res.append(path)
return
for i in range(1,4):
if i<=len(s):
if int(s[:i])<=255:
self.dfs(s[i:],index+1,path+s[:i],res)
if s[0]="0":
break
Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置:
用户信息 当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址。 这样做很重要,因为每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
文本编辑器
$ git config --global core.editor emacs
检查配置信息
$ git config --list
在现有目录中初始化仓库
$ git init
该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪。
如果你是在一个已经存在文件的文件夹(而不是空文件夹)中初始化 Git 仓库来进行版本控制的话,你应该开始跟踪这些文件并提交。 你可通过 git add 命令来实现对指定文件的跟踪,然后执行 git commit 提交:
$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'
克隆现有的仓库
如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想为某个开源项目贡献自己的一份力,这时就要用到git clone 命令。 格式: git clone [url]
$ git clone https://github.com/libgit2/libgit2
请记住,你工作目录下的每一个文件都不外乎这两种状态:已跟踪或未跟踪。 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。
检查当前文件状态
$ git status
$ git status -s #状态简览
跟踪新文件
$ git add
查看已暂存和未暂存的修改 要查看尚未暂存的文件更新了哪些部分,不加参数直接输入 git diff: 请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 然后用 git diff –cached 查看已经暂存起来的变化:(–staged 和 –cached 是同义词)
$ git diff #看暂存前后的变化:
git diff --cached #查看已经暂存起来的变化
提交更新
$ git commit #提交更新
移除文件 要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
移动文件 既然如此,当你看到 Git 的 mv 命令时一定会困惑不已。 要在 Git 中对文件改名,可以这么做:
$ git mv file_from file_to
其实,运行 git mv 就相当于运行了下面三条命令:
$ mv README.md README
$ git rm README.md
$ git add README
*查看提交历史
$ git log
一个常用的选项是 -p,用来显示每次提交的内容差异。 你也可以加上 -2 来仅显示最近两次提交. 如果你想看到每次提交的简略的统计信息,你可以使用 –stat 选项:
撤消操作
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 –amend 选项的提交命令尝试重新提交:
$ git commit --amend
例如,你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作:
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
最终你只会有一个提交 - 第二次提交将代替第一次提交的结果。
取消暂存的文件 演示如何操作暂存区域与工作目录中已修改的文件。 这些命令在修改文件状态的同时,也会提示如何撤消操作。 例如,你已经修改了两个文件并且想要将它们作为两次独立的修改提交,但是却意外地输入了 git add * 暂存了它们两个。
使用 git reset HEAD
撤消对文件的修改
git checkout –
查看远程仓库
$ git remote
$ git remote -v #指定选项 -v,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。
添加远程仓库
git remote add <shortname> <url> #添加远程仓库 shortname:简称 url:地址
现在你可以在命令行中使用字符串 pb 来代替整个 URL。 如果你想拉取 Paul 的仓库中有但你没有的信息,可以运行 git fetch pb
从远程仓库中抓取与拉取
$ git fetch [remote-name] #从远程仓库中获得数据,这个命令会访问远程仓库,从中拉取所有你还没有的数据。
必须注意 git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。
推送到远程仓库 git push [remote-name] [branch-name]
$ git push origin master
只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。
查看远程仓库 如果想要查看某一个远程仓库的更多信息,可以使用 git remote show [remote-name] 命令。
远程仓库的移除与重命名 如果想要重命名引用的名字可以运行 git remote rename 去修改一个远程仓库的简写名。 如果因为一些原因想要移除一个远程仓库 - 你已经从服务器上搬走了或不再想使用某一个特定的镜像了,又或者某一个贡献者不再贡献了 - 可以使用 git remote rm 。
$ git remote rename pb paul #改名
$ git remote rm paul #删除远程仓库
列出标签 Git 使用两种主要类型的标签:轻量标签(lightweight)与附注标签(annotated)。
$ git tag
$ git tag -a v1.4 -m 'my version 1.4' #添加附注标签,-m 选项指定了一条将会存储在标签中的信息。
$ git tag v1.4-lw #添加轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字
$ git show [tagname] #显示标签信息
共享标签 默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样
$ git push origin v1.5 #推送标签v1.5到远程服务器
$ git push origin --tags #推送所有不在远程服务器的标签推送
##2.7 Git 基础 - Git 别名
$ git config --global alias.co checkout #将checkout改为co
$ git config --global alias.br branch #将branch改为br
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --global alias.last 'log -1 HEAD' # 组合改名
第一次参加LeetcodeContest,总共四道题目,限时一个半小时。AC两道:可惜多次提交,罚了太多时间,所以经验就是可以自己在IDE进行调试,保证正确后再提交。
牛人真的太多了,我这个渣渣就多去感受感受。参与第一,比赛第二。不过赛后总结还是要写写,积累经验。
题目描述:给定一个整数列表。每次可以对一个元素进行+1,这个操作叫做一次move。那么最少多少次move,使这个列表内的每个元素都是唯一的。
思路:先对整个数组进行排序。然后遍历,如果pre>=curr,先对res=pre-curr+1,然后令curr=pre+1。最后返回res
class Solution {
public:
int minIncrementForUnique(vector<int>& A) {
sort(A.begin(),A.end());
int res=0;
for(int i=1;i<A.size();i++){
if(A[i]>A[i-1])
continue;
else
res+=A[i-1]-A[i]+1;
A[i]=A[i-1]+1;
}
return res;
}
};
class Solution:
def minIncrementForUnique(self, A):
"""
:type A: List[int]
:rtype: int
"""
if not A:
return 0
A.sort()
ret,pre=0,A[0]
for x in A[1:]:
if x<=pre:
ret+=pre-x+1
pre+=1
else:
pre=x
return ret
题目描述:给出两个序列(序列的每个元素都是不同的),然后一个判断后一个序列能否由前一个序列和一个栈得到。
Example 1: Input: pushed = [1,2,3,4,5], popped = [4,5,3,2,1] Output: true Explanation: We might do the following sequence: push(1), push(2), push(3), push(4), pop() -> 4, push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1 Example 2: Input: pushed = [1,2,3,4,5], popped = [4,3,5,1,2] Output: false Explanation: 1 cannot be popped before 2.
思路:将序列pushed压栈直到栈顶为序列popped的第一个元素
class Solution {
public:
//自己写的丑陋版本,调试了很久才出来
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> s1;
int i=0;
int j=0;
while(j<popped.size()){
while(s1.empty()||s1.top()!=popped[j])
s1.push(pushed[i++]);
while(s1.empty()&&s1.top()==poped[j]){
s1.pop();
j++;
}
if(i=pushed.size()&& j<popped.size() && s1.top()!=poped[j])
return false;
}
return true;
}
};
//别人的简洁代码
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> s;
int i = 0;
for (int x : pushed) {
s.push(x);
while (s.size() && s.top() == popped[i]) {
s.pop();
i++;
}
}
return i == popped.size();
}
38. Count and Say | n | out| | - | :-: | | 1 | 1 | | 2 | 11 | | 3 | 21 | | 4 | 1211| | 5 | 111221|
刚开始做这题的时候,很迷糊。查了一些资料,题意看懂了就比较简单。当n=1,输出就是‘1’,从n=2开始,每个输出就是上个输出的一种描述方式。例如当n=2,由于n=1,out1=1,那么out2的描述就是1个1,所以out2=11.n=3时,out2=12,那么out3的描述就是2个1,所以out3=21.同理out4=1211.依次类推。
编码的思路就和上述思考是一致的。
class Solution {
public:
string countAndSay(int n) {
if(n<=0) return "";
string curr="1";
while(--n){
string next="";
for(int i=0;i<curr.size();i++){
int count=1; //出现次数
while(i+1<curr.size()&&curr[i]==curr[i+1]){
count++;
i++;
}
next+=to_string(count)+curr[i];
}
curr=next;
}
return curr;
}
};
class Solution:
def countAndSay(self, n):
"""
:type n: int
:rtype: str
"""
s = '1'
for _ in range(n - 1):
s = ''.join(str(len(list(group))) + digit
for digit, group in itertools.groupby(s))
return s
思路:使用一个栈便可解决。遍历整个字符串:如果是’(‘、’[‘、’{‘,就将其压栈。如果是’)’、’]’、’}’,就从栈弹出一个元素,如果栈为空或者弹出的元素与遍历到的字符不匹配,就返回false。
C++代码
第一种方式:0ms
class Solution {
public:
bool isValid(string s) {
stack<char> stk;
for(char& c:s){
switch(c){
case '(':stk.push(')');break;
case '[':stk.push(']');break;
case '{':stk.push('}');break;
default:
if(stk.empty()||c!=stk.top()) return false;
else stk.pop();
}
}
return stk.empty();
}
};
第二种方式:4ms
class Solution {
public:
bool isValid(string s) {
stack<char> stk;
for(char c:s){
switch(c){
case '(':stk.push(')');break;
case '[':stk.push(']');break;
case '{':stk.push('}');break;
default:
if(stk.empty()||c!=stk.top()) return false;
else stk.pop();
}
}
return stk.empty();
}
};
这两种方式唯一的区别就是遍历的方式: 第一种使用的是for(char& c:s):这种方式是直接在原字符串进行遍历操作 第二种使用for(char& c:s):这种方式有一个复制原字符串过程、故耗时一些。
python代码
class Solution:
def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
stk=[]
dic= {"]":"[", "}":"{", ")":"("}
for ch in s:
if ch in dic.values():
stk.append(ch)
elif ch in dic.keys():
if stk==[] or stk.pop()!=dic[ch]:
return False
else:
return False
return stk==[]
合理利用Python内建的列表、字典,能有效的简化程序。