一些算法题

1. 转置链表

问题描述:输入一个链表,反转链表后,输出新链表的表头。

示例:

输入

{1,2,3}

输出

{3,2,1}
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

public class Solution {
    public ListNode ReverseList(ListNode head) {
        
        ListNode rHead = null;
        ListNode pNode = head;
        ListNode pPre = null;
        while(pNode != null){
            
            ListNode pNext = pNode.next;
            
            if(pNext == null){
                rHead = pNode;
            }
            
            pNode.next = pPre;
            
            pPre = pNode;
            pNode = pNext;
        }
        
        return  rHead;
    }
}

2. 二维数组的查找

题目描述:

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

public class Solution {
    public boolean Find(int target, int[][] array) {

        // 行
        int m = array.length;
        // 列
        int n = array[0].length;

        if (m == 0 || n == 0) {
            return false;
        }

        int p = 0, q = n - 1;

        while (p < m && q >= 0) {
            if (target == array[p][q]){
                return true;
            }else if(target > array[p][q]){
                ++p;
            }else {
                --q;
            }
        }

        return false;
    }
}

3. 替换空格

题目描述

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

 public String replaceSpace(String s) {
        // 字符串的实际长度
        int length = s.length();
        // 字符串转换为字符数组
        char[] chars = s.toCharArray();
        // 统计字符串空格的数量
        int  numberOfBlank = 0;
        for (char c : chars) {
            if (c == ' '){
                numberOfBlank++;
            }
        }
        // 新数组的长度
        int newLength = length +2*numberOfBlank;
        char[] ch = new char[newLength];
        // 数组中的空格替换为指定字符 本例为%20
        for (int i = 0,j = 0; i < length; i++) {
            if (chars[i] != ' '){
                ch[j++] = chars[i];
            }else{
                ch[j++] = '%';
                ch[j++] = '2';
                ch[j++] = '0';
            }
        }
        return new String(ch);
    }
  public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for(char c:s.toCharArray()){
            sb.append(c==' '?"%20":c);
        }
        return sb.toString();
    }
public String replaceSpace(String s) {
         return s.replaceAll(" ", "%20");
    }

String类的常用方法

public int legth();

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

判断是否是某一个参数开头
   public boolean startsWith(String s)
 判断是否是某一个参数结尾
    public boolean endsWith(String s)
    
    public boolean contains(String s)
    
     public int indexOf(String str)
    
    public String subString(int benginINdex)
    
     public String subString(int benginINdex,int endINdex)
    返回一个字符串,其值是字符串,删除任何前导和尾随空白。
    public String trim()
    

4.从头到尾打印链表

问题描述

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

解法1:反转链表

 public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {

        ArrayList<Integer> arrayList = new ArrayList<>();
        // 判空
        if (listNode == null) {
            return arrayList;
        }
        ListNode head = reverse(listNode);
        // 将结点数据写入arrayList
        do {
            arrayList.add(head.val);
        } while ((head = head.next) != null);
        return arrayList;
    }

    /**
     * 链表转置
     * @param head
     * @return
     */
    public ListNode reverse(ListNode head) {
        // 返回的头 原来链表的尾
        ListNode rNode = null;
        ListNode node = head;
        ListNode preNode = null;

        while (node != null) {
            // 记录当前节点的下一个节点
            ListNode nextNode = node.next;
            // 下一个结点为null 则当前结点node为尾结点
            if (nextNode == null) {
                rNode = node;
            }
            // 交换指针
            node.next = preNode;
            preNode = node;
            node = nextNode;
        }

        return rNode;
    }

不改变链表的结构

先进后出的结构-堆栈

解法2:

使用栈结构 推荐**

 public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {

        ArrayList<Integer> arrayList = new ArrayList<>();
        // 判空
        if (listNode == null) {
            return arrayList;
        }

        Stack<Integer> stack = new Stack<>();
        do {
            // 链表数据进栈
            stack.push(listNode.val);
        } while ((listNode = listNode.next) != null);

        while (!stack.empty()){
            // 堆栈数据添加到list集合
            arrayList.add(stack.pop());
        }
        return arrayList;
    }

解法3:

递归

方法的重载:方法参数不同即可(类型或者参数个数 和返回参数和参数名无关)

 public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        // 判空
        if (listNode == null) {
            return arrayList;
        }
        printListFromTailToHead(arrayList, listNode);
        return arrayList;
    }

    public void printListFromTailToHead(ArrayList<Integer> arrayList, ListNode listNode) {
        if (listNode != null) {
            if (listNode.next != null) {
                printListFromTailToHead(arrayList, listNode.next);
            }
            arrayList.add(listNode.val);
        }
    }

5. 用两个栈实现队列

题目描述

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();

    public void push(int node) {
        stack1.push(node);
    }

    public int pop() {

         if (stack2.size() <= 0  ) {
            while (stack1.size() != 0) {
                Integer data = stack1.pop();
                stack2.push(data);
            }
        }
        return stack2.pop();
    }
}

6. 二进制1的个数

题目描述

输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。

解法一

 public int NumberOf1(int n) {

        int count = 0;
        int flag = 1;
        while (flag != 0){
            if((n & flag) !=0){
                count++;
            }
            flag = flag << 1;
        }
        return count;
    }

解法二

  public int NumberOf2(int n) {

        int count = 0;
        while (n != 0){
            count++;
            n=(n-1)&n;
        }
        return count;
    }

一条语句判断一个整数是不是2的整数次方

把一个整数

public boolean test2(int num) {
       /* int count = 0;
        while (num!=0){
            count++;
            num = (num-1)&num;
        }
        return count;*/

        return ((num - 1) & num) == 0 ? true : false;
    }

7. 携程2019届秋招专业笔试-研发方向 第一题

有一批订单记录,数据有订单号,入店时间,离店时间;
输入一个时间值A,需要在这批记录中找到符合入离店时间范围(A大于等于入店时间,并且A小于等于离店时间)内的所有记录。 单次查询时间复杂度控制在O(logN)
※注意:订单号升序输出 

输入描述:
记录数:10
时间值A:20180602
订单号 入店时间 离店时间
1001 20180103 20180105
1002 20180202 20180203
1003 20180304 20180306
1004 20180401 20180408
1005 20180501 20180504
1006 20180601 20180604
1007 20180705 20180706
1008 20180801 20180804
1009 20180903 20180903
1010 20181003 20181003
以上输入都为整型

输出描述
1006
import java.util.*;

/**
 * @author iforeverhz
 */
public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 输入数据的个数
        int num = in.nextInt();
        // 需要判断的目标 如果在指定时间内 则保存订单号
        int result = in.nextInt();
        // 用于保存满足条件的id
        List<Integer> ids = new ArrayList<>();
        for (int i = 0; i < num; i++) {

            int id = in.nextInt();
            int start = in.nextInt();
            int end = in.nextInt();
            if (result >= start && result <= end) {
                ids.add(id);
            }
        }
        // 判断是否存在数据 有则排序 题目要求升序 否则输出 "null"
        if (ids.size() != 0) {
            //Collections.sort(ids); //默认 升序排序
            Collections.sort(ids, new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    // 升序
                    return o1.compareTo(o2);
                    // 降序
                    //return o2.compareTo(o1);
                }
            });
            for (int i = 0; i < ids.size(); i++) {
                System.out.println(ids.get(i));
            }
        } else {
            System.out.println("null");
        }


    }
}

测试用例
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8.

	设计一个数据结构,实现LRU Cache的功能(Least Recently Used – 最近最少使用缓存)。它支持如下2个操作: get 和 put。

int get(int key) – 如果key已存在,则返回key对应的值value(始终大于0);如果key不存在,则返回-1void put(int key, int value) – 如果key不存在,将value插入;如果key已存在,则使用value替换原先已经存在的值。如果容量达到了限制,LRU Cache需要在插入新元素之前,将最近最少使用的元素删除。

请特别注意“使用”的定义:新插入或获取key视为被使用一次;而将已经存在的值替换更新,不算被使用。

限制:请在O(1)的时间复杂度内完成上述2个操作。

输入描述

第一行读入一个整数n,表示LRU Cache的容量限制。 从第二行开始一直到文件末尾,每1行代表1个操作。

如果每行的第1个字符是p,则该字符后面会跟随2个整数,表示put操作的key和value。

如果每行的第1个字符是g,则该字符后面会跟随1个整数,表示get操作的key。

输出描述

按照输入中get操作出现的顺序,按行输出get操作的返回结果。
输入例子1:
2
p 1 1
p 2 2
g 1
p 2 102
p 3 3
g 1
g 2
g 3
输出例子1:
1
1
-1
3
例子说明1:
2        //Cache容量为2
p 1 1    //put(1, 1)
p 2 2    //put(2, 2)
g 1      //get(1), 返回1
p 2 102  //put(2, 102),更新已存在的key,不算被使用
p 3 3    //put(3, 3),容量超过限制,将最近最少使用的key=2清除
g 1      //get(1), 返回1
g 2      //get(2), 返回-1
g 3      //get(3), 返回3

9. 比赛统计分数问题

import java.util.*;

/**
 * @author iforeverhz
 */
public class Demo {
    public static void main(String[] args) {

        Map<String, Integer> map = new HashMap<>();

        String[] str = new String[26];
        // 模拟数据
        str[0] = "a-b 1:3";
        str[1] = "a-c 2:3";
        str[2] = "b-a 1:1";
        str[3] = "c-a 0:1";
        str[4] = "b-c 4:3";
        str[5] = "c-b 2:2";

        for (int i = 0; str[i] != null; i++) {
            split(map, str[i]);
        }

        // map 排序
        List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
        Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                // 降序排列
                return o2.getValue().compareTo((o1.getValue()));
                // 升序
                //return o1.getValue().compareTo((o2.getValue()));
            }
        });

        // 打印
        String s = "";
        for (Map.Entry<String, Integer> mapping : entries) {
            s += mapping.getKey() + ":" + mapping.getValue() + ",";
        }
        System.out.print(s.substring(0, s.lastIndexOf(',')));

    }

    /**
     * 分解字符串 存入map 集合
     * @param map
     * @param str
     */
    private static void split(Map<String, Integer> map, String str) {


        String team1 = str.substring(0, 1);
        String team2 = str.substring(2, 3);
        int score1 = str.substring(4, 5).getBytes()[0] - '0';
        int score2 = str.substring(6, 7).getBytes()[0] - '0';

        if (score1 > score2) {
            score1 = 3;
            score2 = 0;
        } else if (score1 == score2) {
            score1 = 1;
            score2 = 1;
        } else {
            score1 = 0;
            score2 = 3;
        }
        // 保存比赛中 每一组的得分 key :队名 value:得分
        saveToMap(map, team1, score1);
        saveToMap(map, team2, score2);

    }

    /**
     * 保存得分
     * @param map
     * @param team 队名
     * @param score 得分
     */
    private static void saveToMap(Map<String, Integer> map, String team, int score) {
        // 判断队列是否已经存在
        if (map.containsKey(team)) {
            // 存在 取出已经得分 记录累计得分
            Integer i = map.get(team);
            i += score;
            map.put(team, i);
        } else {
            // 队名不存在的情况
            map.put(team, score);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值