LintCode Cat刷题记录

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<int []>(){
      public int compare(int[] a , int[] b){
            if(a[1]>b[1])  return -1;
            else if(a[1]<b[1])  return 1;
           else {
            if(a[0]>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<T> {

   public int compareTo(T o);
}

若x.compareTo(y) <0,则x<y;若x.compareTo(y) =0,则x=y;若x.compareTo(y) >0,则x=y;

Comparable是一个对象,本身就已经支持自比较所需要实现的接口。

自定义类要在加入list容器中后能够排序,也可以实现Comparable接口。

在用Collections类的sort方法排序时若不指定Comparator,那就以自然顺序排序。所谓自然顺序就是实现Comparable接口设定的排序方式。

若一个类实现了comparable接口,则意味着该类支持排序。如StringInteger自己就实现了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<T> {

    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<Integer,Integer> hm=new HashMap<>();
        for(int i=0;i<numbers.length;i++){
            hm.put(numbers[i],i);
        }
       for(int i=0;i<numbers.length;i++){
            if(hm.containsKey(target-numbers[i]))   {
                arr[0]=Math.min(i,hm.get(target-numbers[i]));
                arr[1]=Math.max(i,hm.get(target-numbers[i]));
                break;
            }
        }
        return arr;
    }
}

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:

  • O(n) Space, O(nlogn) Time
  • O(n) Space, O(n) Time

注意事项

你可以假设只有一组答案。

 public int[] twoSum(int[] numbers, int target) {
        int[] arr=new int[2];
        HashMap<Integer,Integer> hm=new HashMap<>();
        for(int i=0;i<numbers.length;i++){
            hm.put(numbers[i],i);
        }
        for(int i=0;i<numbers.length;i++){
            int temp=numbers[i];
            if(hm.containsKey(target-numbers[i])) {
                arr[0]=Math.min(i,hm.get(target-numbers[i]));
                arr[1]=Math.max(i,hm.get(target-numbers[i]));
                break;
            }
        }
        return arr;
    }

209.给出一个字符串,找出第一个只出现一次的字符。

样例

样例 1:
        输入: "abaccdeff"
        输出:  'b'
        
        解释:
        'b' 是第一个出现一次的字符

样例 2:
        输入: "aabccd"
        输出:  'b'
        
        解释:
        'b' 是第一个出现一次的字符

代码 :

    public char firstUniqChar(String str) {
        HashMap<Character,Integer> hm=new HashMap<>();
        for (int i=0;i<str.length() ;i++ ){
            if(!hm.containsKey(str.charAt(i))) hm.put(str.charAt(i),1);
            else hm.put(str.charAt(i),hm.get(str.charAt(i))+1);
        }
        for (int i=0;i<str.length() ;i++ ){
            if(hm.get(str.charAt(i))==1)  return str.charAt(i);
        }
        return '\0';
    }

   

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<ch.length-1;i++){
            for(int j=i+1;j<ch.length;j++){
                if(ch[i]==ch[j])  return false;
             }
        }
        return true;
     }

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;i<A.length-1;i++){
            for(int j=0;j<A.length-1-i;j++){
                if(A[j]>A[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 (i<j){
            int mid=(i+j)/2;
            if(A[mid]>target)  j=mid-1;
            else if(A[mid]<target) i=mid+1;
            else return mid;
        } 
        if(A[i]>=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<Interval> intervals) {
	        // Write your code here
	        Collections.sort(intervals,new Comparator<Interval>() {

				@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<intervals.get(i-1).end)  return false;
			}
	        return true;
    }

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<val)  p=p.next;
            else {
                ListNode s=new ListNode(val);
                s.next=next;
                p.next=s;
                break;
            }
        }
        return first.next;
    }

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<Integer> reverseStore(ListNode head) {
        // write your code here
        List<Integer> list=new ArrayList<>();
        if(head==null)  return list;
        Stack<Integer> 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<Integer> list=new ArrayList<>();
    public List<Integer> 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<Integer> inorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list=new ArrayList<>();
        Stack<TreeNode>  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<TreeNode>  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<len ;j++ ){
            for (int i=0;i<=j ;i++ ){
                if(ch[i]==ch[j] && (j-i<=2 || dp[i+1][j-1]==1)){
                    dp[i][j]=1;
                    if(res<j-i){
                        res=j-i;
                        str=s.substring(i,j+1);
                    }
                }
            } 
        } 
       return str; 
    }

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值