时隔几日,我又回来啦!继续上篇文章的内容。仍旧是Python和Java双语言版本。
题目目录
198. 打家劫舍
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 1: 输入: [1,2,3,1] 输出: 4 解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 偷窃到的最高金额 = 1 + 3 = 4
class Solution:
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
r = {}
if len(nums) == 0:
return 0
if len(nums) == 1:
return nums[0]
if len(nums) == 2:
return max(nums[0],nums[1])
else:
r[0] = nums[0]
r[1] = max(nums[0],nums[1])
for i in range(2,len(nums)):
r[i] = max(r[i-1],r[i-2]+nums[i])
return r[len(nums)-1]
class Solution {
public int rob(int[] nums) {
if(nums == null || nums.length == 0) return 0;
if(nums.length == 1) return nums[0];
int dp1 = nums[0];
int dp2 = Math.max(dp1, nums[1]);
int dp = dp2;
for(int i = 2; i < nums.length; i++) {
dp = Math.max(dp1 + nums[i], dp2);
dp1 = dp2;
dp2 = dp;
}
return dp;
}
}
202. 快乐数
编写一个算法来判断一个数是不是“快乐数”。
一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。
示例: 输入: 19 输出: true 解释:
class Solution:
def isHappy(self, n):
"""
:type n: int
:rtype: bool
"""
if n < 10:
if n == 1 or n == 7:
return True
else:
return False
new_n = 0
while n:
new_n += (n % 10)**2
n //= 10
return self.isHappy(new_n)
class Solution {
public boolean isHappy(int n) {
Set<Integer> set = new HashSet<Integer>();
while(n!=1&&!set.contains(n))
{
set.add(n);
int sum = 0;
while(n!=0)
{
sum+=Math.pow(n%10,2);
n/=10;
}
n=sum;
}
return n==1;
}
}
203. 移除链表元素
删除链表中等于给定值 val 的所有节点。
示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4->5
class Solution:
def removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
if head:
while head.val == val:
head = head.next
if head is None:
return head
q = head
p = q.next
while p:
if p.val == val:
q.next = p.next
else:
q = q.next
p = p.next
return head
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode root = new ListNode(1);
root.next = head;
ListNode prev = root;
while(prev.next != null){
if(prev.next.val == val){
prev.next = prev.next.next;
}else{
prev = prev.next;
}
}
return root.next;
}
}
204. 计数质数
统计所有小于非负整数 n 的质数的数量。
示例: 输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
# 厄拉多塞筛法
class Solution:
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
if n < 3:
return 0
prime = [1] * n
prime[0] = prime[1] = 0
for i in range(2, int(n**0.5) +1):
if prime[i] == 1:
prime[i*i:n:i] = [0]*len(prime[i*i:n:i])
return sum(prime)
class Solution {
public int countPrimes(int n) {
boolean[] notPrimes = new boolean[n+1];
int res = 0;
for(int i=2;i < n;i++){
if(notPrimes[i]) continue;
res++;
for(int j = 2 * i;j < n;j += i){
notPrimes[j] = true;
}
}
return res;
}
}
205. 同构字符串
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例 1: 输入: s =
"egg",
t ="add"
输出: true
class Solution:
def isIsomorphic(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
l = len(s)
if l == 0 or l == 1:
return True
d = {t[0]:s[0]}
for i in range(1, l):
if s[i] == s[i-1]:
if t[i] == t[i-1]:
continue
else:
return False
else:
if t[i] in d:
if d[t[i]] == s[i]:
continue
else:
return False
else:
d[t[i]] = s[i]
return True
# 大神答案
# return len(set(zip(s,t))) == len(set(s)) == len(set(t))
class Solution {
public boolean isIsomorphic(String s, String t) {
int[] table = new int[512];
for (int i=0; i<s.length(); i++) {
if (table[s.charAt(i)]==0) {
if (table[t.charAt(i)+256]!=0)
return false;
table[s.charAt(i)] = t.charAt(i);
table[t.charAt(i)+256] = 1;
} else {
if (table[s.charAt(i)]!=t.charAt(i))
return false;
}
}
return true;
}
}
206. 反转链表
反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
class Solution:
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
curr = head
newList = None
while curr:
temp = curr.next
curr.next = newList
newList = curr
curr = temp
return newList
class Solution {
public ListNode reverseList(ListNode head) {
ListNode first = head;
ListNode reverseHead = null; //建立一个新的节点用来存放结果
while (first != null) { //遍历输入链表,开始处理每一个节点
ListNode second = first.next; //先处理第一个节点first,所以需要一个指针来存储first的后继
first.next = reverseHead; //将first放到新链表头节点的头部
reverseHead = first; //移动新链表的头指针,让它始终指向新链表头部
first = second; //继续处理原链表的节点,即之前指针存放的后继,循环往复
}
return reverseHead;
}
}
https://blog.csdn.net/SoulOH/article/details/81062223这个博主的图画的非常清楚,不明白的可以去看看。
217. 存在重复元素
给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
示例 1: 输入: [1,2,3,1] 输出: true
# python的优势一下子就体现出来了
class Solution:
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
numsSet = set(nums)
if len(numsSet) != len(nums):
return True
else:
return False
# return len(numsSet) != len(nums)
class Solution {
public boolean containsDuplicate(int[] nums) {
Arrays.sort(nums);
int m=nums.length;
for(int i=0;i<m-1;i++)
{
if(nums[i]==nums[i+1])
return true;
}
return false;
}
}
219. 存在重复元素 II
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。
示例 1: 输入: nums = [1,2,3,1], k = 3 输出: true
class Solution:
def containsNearbyDuplicate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
d = {}
for i in range(len(nums)):
if nums[i] in d:
if abs(i - d[nums[i]]) <= k:
return True
else:
d[nums[i]] = i
d[nums[i]] = i
return False
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
int[] temps = Arrays.copyOf(nums,nums.length);
Arrays.sort(temps);
int temp = 0;
for(int i=0;i<temps.length-1;i++){
if(temps[i]==temps[i+1])
temp = temps[i];
}
for(int j = 0;j<nums.length-1;j++){
if(nums[j]==temp){
for(int index = 1;index<=k;index++){
if(j+index<nums.length&&nums[j+index]==temp)
return true;
}
}
}
return false;
}
}
225. 用队列实现栈
使用队列实现栈的下列操作:
- push(x) -- 元素 x 入栈
- pop() -- 移除栈顶元素
- top() -- 获取栈顶元素
- empty() -- 返回栈是否为空
class MyStack:
def __init__(self):
"""
Initialize your data structure here.
"""
self.stack = []
def push(self, x):
"""
Push element x onto stack.
:type x: int
:rtype: void
"""
self.stack.append(x)
def pop(self):
"""
Removes the element on top of the stack and returns that element.
:rtype: int
"""
if self.stack == []:
return False
else:
return self.stack.pop()
def top(self):
"""
Get the top element.
:rtype: int
"""
if self.stack == []:
return False
else:
return self.stack[-1]
def empty(self):
"""
Returns whether the stack is empty.
:rtype: bool
"""
if self.stack == []:
return True
else:
return False
class MyStack {
LinkedList<Integer> queue;
/** Initialize your data structure here. */
public MyStack() {
queue = new LinkedList<>();
}
/** Push element x onto stack. */
public void push(int x) {
queue.addFirst(x);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue.poll();
}
/** Get the top element. */
public int top() {
return queue.getFirst();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue.isEmpty();
}
}
226. 翻转二叉树
翻转一棵二叉树。
输入:
4 / \ 2 7 / \ / \ 1 3 6 9
输出:
4 / \ 7 2 / \ / \ 9 6 3 1
class Solution:
def invertTree(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
if not root:
return root
self.invertTree(root.left)
self.invertTree(root.right)
root.left, root.right = root.right, root.left
return root
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root!=null){
invertTreeNode(root);//调用 invertTreeNode()方法
}
return root;//root为根节点,root.right为该根节点下对应的子节点
}
public void invertTreeNode(TreeNode root){
if(root!=null){
//先对root.left和root.right交换
TreeNode temp = root.left;
root.left=root.right;
root.right=temp;
//再分别把root.left和root.right作为根节点,递归,分别交换其子节点的值
invertTree(root.left);
invertTree(root.right);
}
}
}
231. 2的幂
给定一个整数,编写一个函数来判断它是否是 2 的幂次方。
示例 1: 输入: 1 输出: true 解释: 20 = 1
class Solution:
def isPowerOfTwo(self, n):
"""
:type n: int
:rtype: bool
"""
if n <= 0:
return False
else:
return bin(n).count('1') == 1
# 大神答案:
# if n < 1:
# return False
# return not(n & (n-1))
class Solution {
public boolean isPowerOfTwo(int n) {
if(n<=0)
return false;
return countBit(n)==1;
}
public int countBit(int num){
int count=0;
while(num!=0){
count+=(num & 1);
num>>=1;
}
return count;
}
}
232. 用栈实现队列
使用栈实现队列的下列操作:
- push(x) -- 将一个元素放入队列的尾部。
- pop() -- 从队列首部移除元素。
- peek() -- 返回队列首部的元素。
- empty() -- 返回队列是否为空。
class MyQueue:
def __init__(self):
"""
Initialize your data structure here.
"""
self._first = []
self._second = []
def push(self, x):
"""
Push element x to the back of queue.
:type x: int
:rtype: void
"""
self._first.append(x)
def pop(self):
"""
Removes the element from in front of queue and returns that element.
:rtype: int
"""
if len(self._first)==0 and len(self._second)==0:
return None
else:
while(self._first):
self._second.append(self._first.pop(0))
ret = self._second[0]
del self._second[0]
return ret
def peek(self):
"""
Get the front element.
:rtype: int
"""
if len(self._first)==0 and len(self._second)==0:
return None
else:
while(self._first):
self._second.append(self._first.pop(0))
return self._second[0]
def empty(self):
"""
Returns whether the queue is empty.
:rtype: bool
"""
return True if len(self._second) == 0 and len(self._first) == 0 else False
class MyQueue {
private Stack<Integer> s1;
private Stack<Integer> s2;
/** Initialize your data structure here. */
public MyQueue() {
s1 = new Stack<>();
s2 = new Stack<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1.push(x);
while (!s2.isEmpty()) {
s1.push(s2.pop());
}
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if (s1.isEmpty()) {
throw new IllegalArgumentException("[ERROR] The queue is empty!");
}
return s1.pop();
}
/** Get the front element. */
public int peek() {
if (s1.isEmpty()) {
throw new IllegalArgumentException("[ERROR] The queue is empty!");
}
return s1.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return s1.isEmpty();
}
}
234. 回文链表
请判断一个链表是否为回文链表。
示例 1: 输入: 1->2 输出: false
示例 2: 输入: 1->2->2->1 输出: true
class Solution:
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head is None or head.next is None:
return True
if head.next.next is None:
return head.val == head.next.val
fast = slow = q = head
while fast.next and fast.next.next:#这里快指针的判读条件跟判断环形有一点不同
fast = fast.next.next
slow = slow.next
def reverse_list(head):
if head is None:
return head
cur = head
pre = None
nxt = cur.next
while nxt:
cur.next = pre
pre = cur
cur = nxt
nxt = nxt.next
cur.next = pre
return cur
p = reverse_list(slow.next)
while p.next:
if p.val != q.val:
return False
p = p.next
q = q.next
return p.val == q.val
class Solution {
//链表原地转置实现o(1)空间复杂度
public static boolean isPalindrome(ListNode head) {
ListNode slow=head;
ListNode fast=head;
if(fast==null||fast.next==null)//0个节点或是1个节点
return true;
while(fast.next!=null&&fast.next.next!=null)
{
fast=fast.next.next;
slow=slow.next;
}
//对链表后半段进行反转
ListNode midNode=slow;
ListNode firNode=slow.next;//后半段链表的第一个节点
ListNode cur=firNode.next;//插入节点从第一个节点后面一个开始
firNode.next=null;//第一个节点最后会变最后一个节点
while(cur!=null)
{
ListNode nextNode=cur.next;//保存下次遍历的节点
cur.next=midNode.next;
midNode.next=cur;
cur=nextNode;
}
//反转之后对前后半段进行比较
slow=head;
fast=midNode.next;
while(fast!=null)
{
if(fast.val!=slow.val)
return false;
slow=slow.next;
fast=fast.next;
}
return true;
}
}
235. 二叉搜索树的最近公共祖先
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
_______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 输出: 6 解释: 节点 2 和节点 8 的最近公共祖先是 6。
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if p.val < root.val and q.val < root.val:
return self.lowestCommonAncestor(root.left, p, q)
elif p.val > root.val and q.val > root.val:
return self.lowestCommonAncestor(root.right, p, q)
else:
return root
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null || p==null || q==null) return null;
if(Math.max(p.val, q.val) < root.val) {
return lowestCommonAncestor(root.left, p, q);
} else if(Math.min(p.val, q.val) > root.val) {
return lowestCommonAncestor(root.right, p, q);
} else return root;
}
}
237. 删除链表中的节点
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。
现有一个链表 -- head = [4,5,1,9],它可以表示为: 4 -> 5 -> 1 -> 9
示例 1: 输入: head = [4,5,1,9], node = 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
242. 有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。
示例 1: 输入: s = "anagram", t = "nagaram" 输出: true
class Solution:
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
if len(t) != len(s):
return False
c = set(t)
for i in c:
if t.count(i) != s.count(i):
return False
return True
class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length())
return false;
int[] sArray = new int[26];
int[] tArray = new int[26];
for (int i = 0; i < s.length(); i++) {
sArray[s.charAt(i)-97] ++;
tArray[t.charAt(i)-97] ++;
}
for (int i = 0; i < 26; i++)
if (sArray[i]!=tArray[i])
return false;
return true;
}
}
257. 二叉树的所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。说明: 叶子节点是指没有子节点的节点。
输入: 1 / \ 2 3 \ 5 输出: ["1->2->5", "1->3"] 解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
class Solution:
def binaryTreePaths(self, root):
"""
:type root: TreeNode
:rtype: List[str]
"""
if not root:
return []
res, stack = [], [(root, "")]
while stack:
node, ls = stack.pop()
if not node.left and not node.right:
res.append(ls + str(node.val))
if node.left:
stack.append((node.left, ls + str(node.val) + "->"))
if node.right:
stack.append((node.right, ls + str(node.val) + "->"))
return res
class Solution {
public List<String> resultList = new ArrayList<String>();
public List<String> binaryTreePaths(TreeNode root) {
findPath(root, new StringBuilder());
return resultList;
}
private void findPath(TreeNode node, StringBuilder sb) {
if (node == null) {
return;
}
int len = sb.length();
sb.append(node.val);
if (node.left == null && node.right == null) {
resultList.add(sb.toString());
} else {
sb.append("->");
findPath(node.left, sb);
findPath(node.right, sb);
}
sb.setLength(len);// 截取 !!!
}
}
258. 各位相加
给定一个非负整数
num
,反复将各个位上的数字相加,直到结果为一位数。示例: 输入:
38
输出: 2 解释: 各位相加的过程为:3 + 8 = 11
,1 + 1 = 2
。 由于2
是一位数,所以返回 2。
class Solution:
def addDigits(self, num):
"""
:type num: int
:rtype: int
"""
if num == 0:
return 0
i = num % 9
return i if i != 0 else 9
class Solution {
public int addDigits(int num) {
while(num>=10){
num=num/10+num%10;
}
return num;
}
}
263. 丑数
编写一个程序判断给定的数是否为丑数。丑数就是只包含质因数
2, 3, 5
的正整数。示例 1: 输入: 6 输出: true 解释: 6 = 2 × 3
class Solution:
def isUgly(self, num):
"""
:type num: int
:rtype: bool
"""
while num >0 and num%2==0:
num /= 2
while num >0 and num%3==0:
num /= 3
while num >0 and num%5==0:
num /= 5
return True if num == 1.0 else False
class Solution {
public boolean isUgly(int num) {
if(num==0) return false;
while(num%2==0) num=num>>1;//二进制运算更快一点
while(num%3==0) num/=3;
while(num%5==0) num/=5;
return num==1?true:false;
}
}
268. 缺失数字
给定一个包含
0, 1, 2, ..., n
中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。示例 1: 输入: [3,0,1] 输出: 2
示例 2: 输入: [9,6,4,2,3,5,7,0,1] 输出: 8
class Solution:
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums.sort()
for key, value in enumerate(nums):
if key != value:
return key
else:
return key + 1
class Solution {
public int missingNumber(int[] nums) {
int sum = 0;
for (int i : nums) {
sum += i;
}
return nums.length * (nums.length + 1) / 2 - sum;
}
}
278. 第一个错误的版本
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有
n
个版本[1, 2, ..., n]
,你想找出导致之后所有版本出错的第一个错误的版本。你可以通过调用
bool isBadVersion(version)
接口来判断版本号version
是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。示例:
给定 n = 5,并且 version = 4 是第一个错误的版本。调用 isBadVersion(3) -> false 调用 isBadVersion(5) -> true 调用 isBadVersion(4) -> true 所以,4 是第一个错误的版本。
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return a bool
# def isBadVersion(version):
class Solution(object):
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
#二分查找,logn的时间复杂度
left=0;right=n
while(True):
mid=(left+right)//2
if isBadVersion(mid)==False and isBadVersion(mid+1)==True:
return mid+1
elif isBadVersion(mid)==False and isBadVersion(mid+1)==False:
left=mid
elif isBadVersion(mid)==True and isBadVersion(mid+1)==True:
right=mid
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int min = 1, max = n, mid = 0;
while(min <= max){
mid = min + (max - min) / 2;
if(isBadVersion(mid)){
max = mid - 1;
} else {
min = mid + 1;
}
}
return min;
}
}
283. 移动零
给定一个数组
nums
,编写一个函数将所有0
移动到数组的末尾,同时保持非零元素的相对顺序。示例: 输入:
[0,1,0,3,12]
输出:[1,3,12,0,0]
# 用Python刷LeetCode有的时候会有一种作弊的感觉
class Solution:
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
n = nums.count(0)
for i in range(n):
nums.remove(0)
nums.extend([0]*n)
class Solution {
public void moveZeroes(int[] nums) {
int length=nums.length;
int index=0;
for(int i=0;i<length;i++){
int now=nums[i];
if(now!=0){
nums[index]=now;
index++;
}
}
if(index!=length){
for(int i=index;i<length;i++){
nums[i]=0;
}
}
return;
}
}
290. 单词模式
给定一种
pattern(模式)
和一个字符串str
,判断str
是否遵循相同的模式。这里的遵循指完全匹配,例如,
pattern
里的每个字母和字符串str
中的每个非空单词之间存在着双向连接的对应模式。示例1: 输入: pattern =
"abba"
, str ="dog cat cat dog"
输出: true
class Solution:
def wordPattern(self, pattern, str):
"""
:type pattern: str
:type str: str
:rtype: bool
"""
l = str.split(' ')
if len(l) != len(pattern):
return False
return len(set(zip(pattern, l))) == len(set(pattern)) == len(set(l))
class Solution {
public boolean wordPattern(String pattern, String str) {
if (pattern==null||pattern.length()==0)
return false;
if (str==null||str.length()==0)
return false;
String [] array = str.split(" ");
if(pattern.length()!=array.length)
return false;
Map<Character,String> map = new HashMap<>();
//去重
Set<Character> set1 = new HashSet<>();
Set<String> set2 = new HashSet<>();
for(int i=0;i<pattern.length();i++){
String temp = map.get(pattern.charAt(i));
if(temp==null){
map.put(pattern.charAt(i),array[i]);
set1.add(pattern.charAt(i));
set2.add(array[i]);
}else {
//先保证两边是单向对应的
if(!temp.equals(array[i]))
return false;
}
}
if(set1.size()==set2.size())
return true;
else
return false;
}
}
292. Nim游戏
你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
输入:4
输出: false 解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛; 因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
class Solution:
def canWinNim(self, n):
"""
:type n: int
:rtype: bool
"""
if (n % 4) == 0:
return False
else:
return True
class Solution {
public boolean canWinNim(int n) {
return (n % 4) == 0 ? false : true;
}
}
303. 区域和检索 - 数组不可变
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。示例:
给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange() sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3
class NumArray:
def __init__(self, nums):
"""
:type nums: List[int]
"""
self.nums = nums
self.cum_sum = [0]
for i in range(len(nums)):
self.cum_sum.append(nums[i] + self.cum_sum[i])
def sumRange(self, i, j):
"""
:type i: int
:type j: int
:rtype: int
"""
return self.cum_sum[j+1] - self.cum_sum[i]
class NumArray {
private int[] nums;
private int[] numi;
public NumArray(int[] nums) {
this.nums = nums;
numi = new int[nums.length+1];
numi[0] = 0;
for(int i=0; i<nums.length; i++){
numi[i+1] = numi[i]+nums[i];
}
}
public int sumRange(int i, int j) {
return numi[j+1]-numi[i];
}
}
326. 3的幂
给定一个整数,写一个函数来判断它是否是 3 的幂次方。
class Solution:
def isPowerOfThree(self, n):
"""
:type n: int
:rtype: bool
"""
while n > 1 :
l = list(map(int, str(n)))
if sum(l) % 3 == 0:
n = n // 3
else:
return False
if n <= 0:
return False
return True
# 大神代码:
# return n > 0 and 1162261467 % n ==0
class Solution {
public boolean isPowerOfThree(int n) {
double x = Math.log10(n) / Math.log10(3.0);
return (int) x - x == 0;
}
}
342. 4的幂
给定一个整数 (32 位有符号整数),请编写一个函数来判断它是否是 4 的幂次方。
class Solution:
def isPowerOfFour(self, num):
"""
:type num: int
:rtype: bool
"""
if num <= 0:
return False
return True if pow(4, int(math.log(num,4))) == num else False
class Solution {
public boolean isPowerOfFour(int num) {
return ((num & (num-1)) == 0) && num > 0 && ((num & 0x55555555) != 0);
}
}
344. 反转字符串
编写一个函数,其作用是将输入的字符串反转过来。
示例 1: 输入: "hello" 输出: "olleh"
class Solution:
def reverseString(self, s):
"""
:type s: str
:rtype: str
"""
return s[::-1]
class Solution {
public String reverseString(String s) {
return new StringBuilder(s).reverse().toString();
}
}
345. 反转字符串中的元音字母
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
class Solution:
def reverseVowels(self, s):
"""
:type s: str
:rtype: str
"""
temp = []
for v in s:
if (v in "aeiouAEIOU"):
temp.append(v)
res = ""
for i in range(len(s)):
if (s[i] in "aeiouAEIOU"):
res += temp.pop()
else:
res += s[i]
return res
# 大神代码,双指针遍历
class Solution:
def reverseVowels(self, s):
"""
:type s: str
:rtype: str
"""
vowels = 'aeiouAEIOU'
i, j = 0, len(s) - 1
list1 = list(s)
while i < j:
if s[j] not in vowels:
j -= 1
elif s[i] not in vowels:
i += 1
else:
list1[i], list1[j] = list1[j], list1[i]
i += 1
j -= 1
return ''.join(list1)
//双指针
class Solution {
private final static Set<Character> set=new HashSet(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));
public String reverseVowels(String s) {
int i=0;
int j=s.length()-1;
char []res=new char [j+1];
while(i<=j){
char chi=s.charAt(i);
char chj=s.charAt(j);
if(!set.contains(chi)){
res[i++]=chi;
}else if(!set.contains(chj)){
res[j--]=chj;
}else {
res[i++]=chj;
res[j--]=chi;
}
}
return new String(res);
}
}
349. 两个数组的交集
给定两个数组,编写一个函数来计算它们的交集。
class Solution:
def intersection(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
return list(set(nums1)&set(nums2))
class Solution {
public static int[] intersection(int[] nums1, int[] nums2){
Set<Integer> nums = new HashSet<Integer>();
Set<Integer> result = new HashSet<>();
for(int i=0;i<nums2.length;i++) {
nums.add(nums2[i]);//放入时候去掉重复的
}
for(int i=0;i<nums1.length;i++) {
if(nums.contains(nums1[i])) {
result.add(nums1[i]);//放入交集
}
}
int[] res = new int[result.size()];
int i=0;
Iterator iter = result.iterator();
while(iter.hasNext()){
res[i++]=(int)iter.next(); //集合变数组
}
return res;
}
}
350. 两个数组的交集 II
给定两个数组,编写一个函数来计算它们的交集。
示例 1: 输入: nums1 = [1,2,2,1], nums2 = [2,2] 输出: [2,2]
class Solution:
def intersect(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
res = []
dict = {}
for num in nums1:
if num not in dict:
dict[num] = 1
else:
dict[num] += 1
for num in nums2:
if num in dict and dict[num] > 0:
dict[num] -= 1
res.append(num)
return res
class Solution {
public static int[] intersect(int[] nums1, int[] nums2){
Arrays.sort(nums1);//排序
Arrays.sort(nums2);
ArrayList result = new ArrayList();
for (int i = 0, j = 0; i < nums1.length && j < nums2.length; ){
if (nums1[i] == nums2[j]){
result.add(nums1[i]);
i++;
j++;
} else if (nums1[i] < nums2[j]) {
i++;
} else {
j++;
}
}
int[] res = new int[result.size()];
for (int i = 0; i < result.size(); i++){
res[i] = (int) result.get(i);
}
return res;
}
}
367. 有效的完全平方数
给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。
说明:不要使用任何内置的库函数,如
sqrt
。
class Solution:
def isPerfectSquare(self, num):
"""
:type num: int
:rtype: bool
"""
l = 1
h = num
while l <= h:
mid = (l+h)//2
t = mid**2
if t < num:
l = mid + 1
elif t == num:
return True
else:
h = mid - 1
return False
class Solution {
public boolean isPerfectSquare(int num) {
int i = 1;
while (num > 0) {
num -= i;
i += 2;
}
return num == 0;
}
}
371. 两整数之和
不使用运算符
+
和-
,计算两整数a
、b
之和。
class Solution:
def getSum(self, a, b):
"""
:type a: int
:type b: int
:rtype: int
"""
while b != 0:
carry = a & b
a = (a ^ b) % 0x100000000
b = (carry << 1) % 0x100000000
return a if a <= 0x7FFFFFFF else a | (~0x100000000+1)
class Solution {
public int getSum(int a, int b) {
if(b == 0) return a;
return getSum(a^b, (a&b)<<1);
}
}
374. 猜数字大小
我们正在玩一个猜数字游戏。 游戏规则如下:
我从 1 到 n 选择一个数字。 你需要猜我选择了哪个数字。
每次你猜错了,我会告诉你这个数字是大了还是小了。
你调用一个预先定义好的接口guess(int num)
,它会返回 3 个可能的结果(-1
,1
或0
):-1 : 我的数字比较小 1 : 我的数字比较大 0 : 恭喜!你猜对了!
class Solution(object):
def guessNumber(self, n):
"""
:type n: int
:rtype: int
"""
l = 1
h = n
while l <= h :
mid = (l+h)//2
if not guess(mid):
return mid
elif guess(mid) == -1:
h = mid - 1
else:
l = mid + 1
public class Solution extends GuessGame {
public int guessNumber(int n) {
int low=1,high=n;
while(low<=high) {
int mid=(high-low)/2+low;
int g=guess(mid);
if(g==1)//中间数比目标数小
low=mid+1;
else if(g==-1)//中间数比目标数大
high=mid-1;
else return mid;
}
return -1;
}
}
383. 赎金信
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。)
class Solution:
def canConstruct(self, ransomNote, magazine):
"""
:type ransomNote: str
:type magazine: str
:rtype: bool
"""
for i in ransomNote:
if i in magazine:
magazine = magazine.replace(i,'',1)
else:
return False
return True
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] res = new int[26];
for(int i=0;i<magazine.length();i++){
res[magazine.charAt(i)-'a']++;
}
for(int i=0;i<ransomNote.length();i++){
int k = -- res[ransomNote.charAt(i) - 'a'];
if(k<0)
return false;
}
return true;
}
}
387. 字符串中的第一个唯一字符
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
class Solution:
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
dic = collections.Counter(s)
for i in range(len(s)):
if dic[s[i]] == 1:
return i
return -1
class Solution {
public int firstUniqChar(String s) {
int freq[] = new int[26];
for (int i = 0; i < s.length(); i++)
freq[s.charAt(i) - 'a']++;
for (int i = 0; i < s.length(); i++)
if (freq[s.charAt(i) - 'a'] == 1)
return i;
return -1;
}
}
389. 找不同
给定两个字符串 s 和 t,它们只包含小写字母。字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。
class Solution:
def findTheDifference(self, s, t):
"""
:type s: str
:type t: str
:rtype: str
"""
r = list(set(t))
for i in r:
if s.count(i) != t.count(i):
return i
class Solution {
public char findTheDifference(String s, String t) {
int cou = 0;
for (int i =0;i<s.length();i++){
cou -= (int)s.charAt(i);
}
for (int i =0;i<t.length();i++){
cou += (int)t.charAt(i);
}
return (char)cou;
}
}
400. 第N个数字
在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...中找到第 n 个数字。
注意: n 是正数且在32为整形范围内 ( n < 2^31)。
class Solution:
def findNthDigit(self, n):
"""
:type n: int
:rtype: int
"""
digit = 1
while n > digit * 9 * (10**(digit-1)):
n -= digit * 9 * (10**(digit-1))
digit += 1
a = (n - 1) // digit
b = (n - 1) % digit
num = 10**(digit - 1) + a
return int(str(num)[b])
class Solution {
public int findNthDigit(int n) {
int len = 1;
long count = 9;
int start = 1;
while (n > len * count) {
n -= len * count;
len += 1;
count *= 10;
start *= 10;
}
start += (n - 1)/ len;
String s = Integer.toString(start);
return Character.getNumericValue(s.charAt((n - 1) % len));
}
}
401. 二进制手表
二进制手表顶部有 4 个 LED 代表小时(0-11),底部的 6 个 LED 代表分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。
class Solution(object):
def readBinaryWatch(self, num):
"""
:type num: int
:rtype: List[str]
"""
a={0: ['0'], 1: ['1', '2', '4', '8'], 2: ['3', '5', '6', '9', '10'], 3: ['7', '11']}
b={0: ['00'], 1: ['01', '02', '04', '08', '16', '32'], 2: ['03', '05', '06', '09', '10', '12', '17', '18', '20', '24', '33', '34', '36', '40', '48'], 3: ['07', '11', '13', '14', '19', '21', '22', '25', '26', '28', '35', '37', '38', '41', '42', '44', '49', '50', '52', '56'], 4: ['15', '23', '27', '29', '30', '39', '43', '45', '46', '51', '53', '54', '57', '58'], 5: ['31', '47', '55','59']}
if num<0 or num>8:
return []
mi=max(0,num-5)
mx=min(3,num)
res=[]
for i in range(mi,mx+1):
for x in a[i]:
for y in b[num-i]:
res.append(x+':'+y)
return res
public class Solution {
int[] led = new int[]{1,2,4,8,1,2,4,8,16,32};
public List<String> readBinaryWatch(int num) {
List<String> rs = new ArrayList<>();
dfs(rs,num,0,0,0);
Collections.sort(rs);
return rs;
}
public void dfs(List<String> rs,int num,int i,int sum0,int sum1) {
if(sum0>11||sum1>59)return;
if(num==0) {
StringBuilder sb =new StringBuilder();
sb.append(String.valueOf(sum0)).append(':');
if(sum1<10)sb.append('0').append(String.valueOf(sum1));
else sb.append(String.valueOf(sum1));
rs.add(sb.toString());
}
if(num>0&&i<=9) {
if(i<=3) {
dfs(rs,num,i+1,sum0,sum1);
sum0+=led[i];
num--;
dfs(rs,num,i+1,sum0,sum1);
}
else {
dfs(rs,num,i+1,sum0,sum1);
sum1+=led[i];
num--;
dfs(rs,num,i+1,sum0,sum1);
}
}
}
}
404. 左叶子之和
计算给定二叉树的所有左叶子之和。
class Solution:
def sumOfLeftLeaves(self, root):
"""
:type root: TreeNode
:rtype: int
"""
result = 0
if not root:
return 0
if root.left and not root.left.left and not root.left.right:
result += root.left.val
return result + self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right)
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
int sum = 0;
if (root != null){
if (root.left != null){
if (root.left.left == null && root.left.right ==null){
sum += root.left.val;
}
sum += sumOfLeftLeaves(root.left);
}
if (root.right != null){
sum += sumOfLeftLeaves(root.right);
}
}
return sum;
}
}
405. 数字转换为十六进制数
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
class Solution:
def toHex(self, num):
"""
:type num: int
:rtype: str
"""
if num < 0:
num += 0x100000000
if num == 0:
return '0'
res = ''
hexVal = '0123456789abcdef'
while num:
val = num&0xf # 这个地方可以把0xf换成15,但会拖慢速度
res += hexVal[val]
num = num >> 4 if num > 0 else (num+0x100000000) >> 4
return res[::-1]
class Solution {
public String toHex(int num) {
if(num==0)
return "0";
String[] map = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
StringBuilder str = new StringBuilder();
while(num!=0)
{
str.insert(0,map[(num&15)]);
//此为无符号右移4位等于除以16
num>>>=4;
}
return str.toString();
}
}
409. 最长回文串
给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。
在构造过程中,请注意区分大小写。比如
"Aa"
不能当做一个回文字符串。
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: int
"""
#思路不是将其排列,排列不止一种,采用字典
dict={}
length=0
k=0
for s1 in s:
if s1 not in dict:
dict[s1]=1
else:
dict[s1]+=1
for value in dict.values():
if value%2==0:#双数
length+=value
else:
length+=value-1#当为单数时,可去掉一个变成双数
k=1#单数只能出现一次
return length+k
class Solution {
public int longestPalindrome(String s) {
//利用set集合来做。
Set<Character> hs=new HashSet<Character>();
int count=0;
for(int i=0;i<s.length();i++) {
if(hs.contains(s.charAt(i))) {
hs.remove(s.charAt(i));
count++;
}else hs.add(s.charAt(i));
}
if(!hs.isEmpty()) return count*2+1;
else return count*2;
}
}
412. Fizz Buzz
写一个程序,输出从 1 到 n 数字的字符串表示。
1. 如果 n 是3的倍数,输出“Fizz”;
2. 如果 n 是5的倍数,输出“Buzz”;
3.如果 n 同时是3和5的倍数,输出 “FizzBuzz”。
class Solution:
def fizzBuzz(self, n):
"""
:type n: int
:rtype: List[str]
"""
result = []
for i in range(1, n+1):
if i%3 == 0 and i%5 == 0:
result.append("FizzBuzz")
elif i%3 == 0:
result.append("Fizz")
elif i%5 == 0:
result.append("Buzz")
else:
result.append(str(i))
return result
class Solution {
public List<String> fizzBuzz(int n) {
List<String> list = new ArrayList<String>();
for(int i = 1;i <= n;i++){
if((i % 3 == 0) && (i % 5 == 0)){
list.add("FizzBuzz");
}else if(i % 3 == 0){
list.add("Fizz");
}else if(i % 5 == 0){
list.add("Buzz");
}else{
list.add(i+"");
}
}
return list;
}
}
414. 第三大的数
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
class Solution:
def thirdMax(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res = [float("-inf")] * 3
for i in nums:
if i in res:
continue
if i > res[0]:
res = [i,res[0],res[1]]
elif i > res[1]:
res = [res[0],i,res[1]]
elif i > res[2]:
res = [res[0],res[1],i]
return res[-1] if res[2] != float("-inf") else res[0]
class Solution {
public int thirdMax(int[] nums) {
long max1 = Long.MIN_VALUE;
long max2 = Long.MIN_VALUE;
long max3 = Long.MIN_VALUE;
for (int num: nums) {
if (num <= max3 || num == max2 || num == max1) {
continue;
} else if (num < max2) {
max3 = num;
} else if (num < max1) {
max3 = max2;
max2 = num;
} else {
max3 = max2;
max2 = max1;
max1 = num;
}
}
if (max3 != Long.MIN_VALUE) {
return (int)max3;
} else {
return (int)max1;
}
}
}
415. 字符串相加
给定两个字符串形式的非负整数
num1
和num2
,计算它们的和。
class Solution(object):
def addStrings(self, num1, num2):
"""
:type num1: str
:type num2: str
:rtype: str
"""
return str(int(num1) + int(num2))
class Solution {
public String addStrings(String num1, String num2) {
StringBuilder sb=new StringBuilder();
//表示向前进一位
int pre=0;
while(num1.length()!=num2.length()){
if(num1.length()>num2.length())
num2="0"+num2;
else
num1="0"+num1;
}
char[] c1 = num1.toCharArray();
char[] c2 = num2.toCharArray();
for(int i=num1.length()-1;i>=0;i--){
int m=c1[i]-'0';
int n=c2[i]-'0';
int temp=m+n+pre;
if(temp>=10){
sb.append(temp-10);
pre=1;
}
else{
sb.append(temp);
pre=0;
}
}
if(pre==1)
sb.append('1');
return sb.reverse().toString();
}
}
434. 字符串中的单词数
统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。请注意,你可以假定字符串里不包括任何不可打印的字符。
class Solution:
def countSegments(self, s):
"""
:type s: str
:rtype: int
"""
return len(s.split())
class Solution {
public int countSegments(String s) {
if(s==null||s.length()==0)return 0;
int i=0,j,count=0;
while(i<s.length()){
while(i<s.length()&&s.charAt(i)==' ')i++;//i每次移到第一个非空格处
j=i;
while(j<s.length()&&s.charAt(j)!=' ')j++;//j每次移到第一个空格处,i和j之间就是一个单词
if(i<j){
i=j;
count++;
}else{
return count;//当最后一个单词后面有空格时,从此出口结束。
}
}
return count;//当最后一个单词后面没有空格时,从此出口结束。
}
}