846. 多关键字排序
给定 n 个学生的学号(从 1 到 n 编号)以及他们的考试成绩,表示为(学号,考试成绩),请将这些学生按考试成绩降序排序,若考试成绩相同,则按学号升序排序。
样例
样例1
输入: array = [[2,50],[1,50],[3,100]]
输出: [[3,100],[1,50],[2,50]]
样例2
输入: array = [[2,50],[1,50],[3,50]]
输出: [[1,50],[2,50],[3,50]]
public class Solution {
public int[][] multiSort(int[][] array) {
Arrays.sort(array,new Comparator(){
public int compare(int[] a , int[] b){
if(a[1]>b[1]) return -1;
else if(a[1]b[0] ) return -1;
else return 1;
}
}
})
思路 :
思路 :ComParator 和 Comparable区别
java中,对集合对象或者数组对象排序,有两种实现方式。
即:(1)对象实现Comparable 接口
(2)定义比较器,实现Comparator接口。
Comparable介绍
Comparable是在集合内部定义的方法实现的排序,位于java.lang下。
Comparable 接口仅仅只包括一个函数,它的定义如下:
package java.lang;
import java.util.*;
public interface Comparable {
public int compareTo(T o);
}
若x.compareTo(y) <0,则x
Comparable是一个对象,本身就已经支持自比较所需要实现的接口。
自定义类要在加入list容器中后能够排序,也可以实现Comparable接口。
在用Collections类的sort方法排序时若不指定Comparator,那就以自然顺序排序。所谓自然顺序就是实现Comparable接口设定的排序方式。
若一个类实现了comparable接口,则意味着该类支持排序。如String、Integer自己就实现了Comparable接口,可完成比较大小操作。
一个已经实现comparable的类的对象或数据,可以通过Collections.sort(list) 或者Arrays.sort(arr)实现排序。通过Collections.sort(list,Collections.reverseOrder());对list进行倒序排列。
Comparator介绍
Comparator是在集合外部实现的排序,位于java.util下。
Comparator接口包含了两个函数。
package java.util;
public interface Comparator {
int compare(T o1, T o2);
boolean equals(Object obj);
}
我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以新建一个该类的比较器来进行排序。这个比较器只需要实现comparator即可。
如果引用的为第三方jar包,这时候,没办法改变类本身,可是使用这种方式。
Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。
Comparator体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
comparable相当于内部比较器。comparator相当于外部比较器。
1. A + B 问题
中文English
给出两个整数 aa 和 bb , 求他们的和。
挑战:不用加号
思路 : 异或与左移等操作可以实现加法
代码实现 :
public class Solution {
public int aplusb(int a, int b) {
while((a & b)!=0){
int temp=a;
a=(a&b)<<1;
b=temp ^ b ;
}
return a ^ b;
}
}
8. 旋转字符串
中文English
给定一个字符串(以字符数组的形式给出)和一个偏移量,根据偏移量原地旋转字符串(从左向右旋转)
样例
样例 1:
输入: str="abcdefg", offset = 3
输出: "efgabcd"
挑战
在数组上原地旋转,使用O(1)的额外空间
注意事项
offset >= 0
思路 : 合理使用HashMap 键唯一 值可以不唯一
代码实例 :
public class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] arr=new int[2];
HashMap hm=new HashMap<>();
for(int i=0;i
56. 两数之和
给一个整数数组,找到两个数使得他们的和等于一个给定的数 target。
你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1。
样例
Example1:
给出 numbers = [2, 7, 11, 15], target = 9, 返回 [0, 1].
Example2:
给出 numbers = [15, 2, 7, 11], target = 9, 返回 [1, 2].
挑战
Either of the following solutions are acceptable:
注意事项
你可以假设只有一组答案。
public int[] twoSum(int[] numbers, int target) {
int[] arr=new int[2];
HashMap hm=new HashMap<>();
for(int i=0;i
209.给出一个字符串,找出第一个只出现一次的字符。
样例
样例 1:
输入: "abaccdeff"
输出: 'b'
解释:
'b' 是第一个出现一次的字符
样例 2:
输入: "aabccd"
输出: 'b'
解释:
'b' 是第一个出现一次的字符
代码 :
public char firstUniqChar(String str) {
HashMap hm=new HashMap<>();
for (int i=0;i
82. 落单的数
中文English
给出2*n + 1 个的数字,除其中一个数字之外其他每个数字均出现两次,找到这个数字。
样例
给出 [1,2,2,1,3,4,3],返回 4
挑战
一次遍历,常数级的额外空间复杂度
思路 :相同数字异或为0
代码实现 :
public int singleNumber(int[] A) {
int temp=0;
for(int t:A){
temp=temp^t;
}
return temp;
}
13. 字符串查找
中文English
对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1。
样例
样例 1:
输入: source = "source" , target = "target"
输出:-1
样例解释:
如果source里没有包含target的内容,返回-1
样例 2:
输入: source = "abcdabcdefg" ,target = "bcd"
输出: 1
样例解释:
如果source里包含target的内容,返回target在source里第一次出现的位置
代码实现 :
public int strStr(String source, String target) {
// Write your code here
if(target.length()<=0) return 0;
if(target.length()>0 && source.length()<=0) return -1;
int i=0,j=0;
int temp=Integer.MIN_VALUE;
while (true){
if(source.charAt(i)==target.charAt(j)){
j++;i++;
if(j==target.length()) return i-j;
if(i==source.length()) return -1;
if(temp==Integer.MIN_VALUE && source.charAt(i)==target.charAt(0))
temp=i;
}else{
if(temp!=Integer.MIN_VALUE) {
j=0;i=temp;
temp=Integer.MIN_VALUE;
}else{
i++;j=0;
}
}
// if(j==target.length()) return i-j;
// if(i==source.length()) return -1;
if(i==source.length()) return -1;
}
}
157. 判断字符串是否没有重复字符
中文English
实现一个算法确定字符串中的字符是否均唯一出现
样例
Example 1:
Input: "abc_____"
Output: false
Example 2:
Input: "abc"
Output: true
代码实现 :
public boolean isUnique(String str) {
// write your code here
char[] ch=str.toCharArray();
for(int i=0;i
53. 翻转字符串中的单词
中文English
给定一个字符串,逐个翻转字符串中的每个单词。
样例
样例 1:
输入: "the sky is blue"
输出: "blue is sky the"
样例解释:
返回逐字反转的字符串.
样例 2:
输入: "hello world"
输出: "word hello"
样例解释:
返回逐字反转的字符串.
思路 :合理利用trim() 去除空格
代码实现 :
public String reverseWords(String s) {
// write your code here
StringBuffer sb=new StringBuffer();
String[] str=s.split(" ");
for(int i=str.length-1;i>=0;i--){
if(str[i].trim().length()>0 ) sb.append(str[i].trim()+" ");
}
return sb.toString().trim();
}
463. 整数排序
中文English
给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法。
样例
样例 1:
输入: [3, 2, 1, 4, 5]
输出: [1, 2, 3, 4, 5]
样例解释:
返回排序后的数组。
样例 2:
输入: [1, 1, 2, 1, 1]
输出: [1, 1, 1, 1, 2]
样例解释:
返回排好序的数组。
代码实现 :
public void sortIntegers(int[] A) {
// write your code here
for(int i=0;iA[j+1]){
int temp=A[j];
A[j]=A[j+1];
A[j+1]=temp;
}
}
}
}
60. 搜索插入位置
中文English
给定一个排序数组和一个目标值,如果在数组中找到目标值则返回索引。如果没有,返回到它将会被按顺序插入的位置。
你可以假设在数组中无重复元素。
样例
[1,3,5,6],5 → 2
[1,3,5,6],2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6],0 → 0
挑战
时间复杂度为O(log(n))
思路 :时间复杂度为O(logn) 优先考虑二分查找
代码实现 :
public int searchInsert(int[] A, int target) {
// write your code here
if(A.length<=0) return 0;
if(A.length==1 && A[0]==target) return 0;
int i=0,j=A.length-1;
while (itarget) j=mid-1;
else if(A[mid]=target ) return i;
else return i+1;
}
920. 会议室
中文English
给定一系列的会议时间间隔,包括起始和结束时间[[s1,e1],[s2,e2],…(si < ei),确定一个人是否可以参加所有会议。
样例
样例1
输入: intervals = [(0,30),(5,10),(15,20)]
输出: false
解释:
(0,30), (5,10) 和 (0,30),(15,20) 这两对会议会冲突
样例2
输入: intervals = [(5,8),(9,15)]
输出: true
解释:
这两个时间段不会冲突
思路 : 比较器
代码实现 :
public boolean canAttendMeetings(List intervals) {
// Write your code here
Collections.sort(intervals,new Comparator() {
@Override
public int compare(Interval o1, Interval o2) {
// TODO Auto-generated method stub
if(o1.start>=o2.start) return 1;
else return -1;
}
});
for (int i = 1; i < intervals.size(); i++) {
if(intervals.get(i).start
219. 在排序链表中插入一个节点
中文English
在链表中插入一个节点。
样例
样例 1:
输入:head = 1->4->6->8->null, val = 5
输出:1->4->5->6->8->null
样例 2:
输入:head = 1->null, val = 2
输出:1->2->null
思路 : 因为可能会有插入在链表头结点的位置的情况,所以要定义一个节点指向要排序的链表头结点
代码实现 :
public ListNode insertNode(ListNode head, int val) {
// write your code here
ListNode first=new ListNode(0);
first.next=head;
ListNode p=first;
while (p!=null){
ListNode next=p.next;
if(next!=null && next.val
466. 链表节点计数
中文English
计算链表中有多少个节点.
样例
样例 1:
输入: 1->3->5->null
输出: 3
样例解释:
返回链表中结点个数,也就是链表的长度.
样例 2:
输入: null
输出: 0
样例解释:
空链表长度为0
注意事项 : 空链表的情况要单独列出
代码实现 :
public int countNodes(ListNode head) {
// write your code here
if(head==null) return 0;
int sum=0;
while (head!=null) {
sum++;
head=head.next;
}
return sum;
}
822. 相反的顺序存储
中文English
给出一个链表,并将链表的值以倒序存储到数组中。
样例
样例1
输入: 1 -> 2 -> 3 -> null
输出: [3,2,1]
样例2
输入: 4 -> 2 -> 1 -> null
输出: [1,2,4]
思路 : 利用栈的先进后出的特点可以实现逆序输出
代码实现 :
public List reverseStore(ListNode head) {
// write your code here
List list=new ArrayList<>();
if(head==null) return list;
Stack st=new Stack<>();
while (head!=null) {
st.push(head.val);
head=head.next;
}
while(!st.isEmpty()){
list.add(st.pop());
}
return list;
}
67. 二叉树的中序遍历
中文English
给出一棵二叉树,返回其中序遍历
样例
给出二叉树 {1,#,2,3},
1
\
2
/
3
返回 [1,3,2].
挑战
你能使用非递归算法来实现么?
递归实现 :
List list=new ArrayList<>();
public List inorderTraversal(TreeNode root) {
// write your code here
if(root==null) return list;
Help(root);
return list;
}
void Help(TreeNode proot){
if(proot!=null){
if(proot.left!=null) Help(proot.left);
list.add(proot.val);
if(proot.right!=null) Help(proot.right);
}
}
非递归实现 :(要熟悉二叉树的前序,中序,后续非递归遍历)
public List inorderTraversal(TreeNode root) {
// write your code here
List list=new ArrayList<>();
Stack st=new Stack<>();
TreeNode proot=root;
while (proot!=null|| !st.empty()){
if(proot!=null ){
st.push(proot);
proot=proot.left;
} else{
TreeNode node=st.pop();
list.add(node.val);
proot=node.right;
}
}
return list;
}
175. 翻转二叉树
中文English
翻转一棵二叉树
样例
样例 1:
输入: {1,3,#}
输出: {1,#,3}
解释:
1 1
/ => \
3 3
样例 2:
输入: {1,2,3,#,#,4}
输出: {1,3,2,#,4}
解释:
1 1
/ \ / \
2 3 => 3 2
/ \
4 4
挑战
递归固然可行,能否写个非递归的?
递归实现 :
public void invertBinaryTree(TreeNode root) {
// write your code here
if(root!=null){
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
invertBinaryTree(root.left);
invertBinaryTree(root.right);
}
}
非递归实现:(自顶向下翻转)
public void invertBinaryTree(TreeNode root) {
// write your code here
if(root==null) return ;
Stack st=new Stack<>();
st.push(root);
while (!st.empty()){
TreeNode temp=st.pop();
TreeNode node=temp.left;
temp.left=temp.right;
temp.right=node;
if(temp.left!=null) st.push(temp.left);
if(temp.right!=null) st.push(temp.right);
}
}
200. 最长回文子串
中文English
给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。
样例
样例 1:
输入:"abcdzdcab"
输出:"cdzdc"
样例 2:
输入:"aba"
输出:"aba"
思路 :典型递归思想
代码实现 :
public String longestPalindrome(String s) {
// write your code here
char[] ch=s.toCharArray();
int len=ch.length;
int res=Integer.MIN_VALUE;
String str="";
int dp[][]=new int[len][len];
for (int j=0;j