• 牛客网刷题


    ced485cbb11e458d81a746890b32cf3f.gif

     作者:敲代码の流川枫

    博客主页:流川枫的博客

    专栏:和我一起学java

    语录:Stay hungry stay foolish

    工欲善其事必先利其器,给大家介绍一款超牛的斩获大厂offer利器——牛客网

    点击注册和我一起刷题

     

    文章目录

    1.字符串中的第一个唯一字符

    2. 只出现一次的数字

    3.复制带随机指针的链表


    1.字符串中的第一个唯一字符

    给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

    在第一次遍历时,我们使用计数数组统计出字符串中每个字符出现的次数。在第二次遍历时,我们只要遍历到了一个只出现一次的字符,那么就返回它的索引,否则在遍历结束后返回 −1

    1. class Solution {
    2. public int firstUniqChar(String s) {
    3. int[] arr = new int[26];
    4. for(int i = 0;i<s.length();i++){
    5. char ch = s.charAt(i);
    6. arr[ch-'a']++;
    7. }
    8. for(int i = 0;i<s.length();i++){
    9. char ch1 = s.charAt(i);
    10. if(arr[ch1-'a'] == 1){
    11. return i;
    12. }
    13. }
    14. return -1;
    15. }
    16. }

    2. 只出现一次的数字

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

    说明:

    你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

    解法一:异或

    异或解法:异或运算满足交换律,a^b^a=a^a^b=b,因此ans相当于nums[0]^nums[1]^nums[2]^nums[3]^nums[4]..... 然后再根据交换律把相等的合并到一块儿进行异或(结果为0),然后再与只出现过一次的元素进行异或,这样最后的结果就是,只出现过一次的元素(0^任意值=任意值)

    1. class Solution {
    2. public int singleNumber(int[] nums) {
    3. int ret = nums[0];
    4. if(nums.length > 1){
    5. for(int i = 1;i<nums.length;i++){
    6. ret = ret ^ nums[i];
    7. }
    8. }
    9. return ret;
    10. }
    11. }

    解法二:HashSet

    遍历数组,如果set不包含这个值,就添加,如果包含就删除,最后没被删除的就是只出现一次的数字

    1. class Solution {
    2. public int singleNumber(int[] nums) {
    3. HashSet<Integer> set = new HashSet<>();
    4. for(int i =0 ;i< nums.length;i++){
    5. if(!set.contains(nums[i])){
    6. set.add(nums[i]);
    7. }
    8. else{
    9. set.remove(nums[i]);
    10. }
    11. }
    12. for(int i =0;i<nums.length;i++){
    13. if(set.contains(nums[i])){
    14. return nums[i];
    15. }
    16. }
    17. return -1;
    18. }
    19. }

    3.复制带随机指针的链表

    给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

    我们用哈希表来解决这个问题
    首先创建一个哈希表,再遍历原链表,遍历的同时再不断创建新节点
    我们将原节点作为key,新节点作为value放入哈希表中

    第二步我们再遍历原链表,这次我们要将新链表的next和random指针给设置上 

    我们可以发现,原节点和新节点是一一对应的关系,所以

    map.get(原节点),得到的就是对应的新节点
    map.get(原节点.next),得到的就是对应的新节点.next
    map.get(原节点.random),得到的就是对应的新节点.random

    所以,我们只需要再次遍历原链表,然后设置:
    新节点.next -> map.get(原节点.next)
    新节点.random -> map.get(原节点.random)
    这样新链表的next和random都被串联起来了
    最后,我们然后map.get(head),也就是对应的新链表的头节点,就可以解决此问题

    代码

    1. class Solution {
    2. public Node copyRandomList(Node head) {
    3. if(head==null) {
    4. return null;
    5. }
    6. HashMap<Node,Node> map = new HashMap<>();
    7. Node cur = head;
    8. while(cur != null){
    9. Node node = new Node(cur.val);
    10. map.put(cur,node);
    11. cur = cur.next;
    12. }
    13. cur = head;
    14. while(cur != null){
    15. map.get(cur).next = map.get(cur.next);
    16. map.get(cur).random = map.get(cur.random);
    17. cur = cur.next;
    18. }
    19. return map.get(head);
    20. }
    21. }

     

  • 相关阅读:
    五分钟快速搭建一个实时人脸口罩检测系统(OpenCV+PaddleHub 含源码)
    UE4 创建暂停和结束游戏UI
    六级高频词汇
    我用Redis分布式锁,抢了瓶茅台,然后GG了~~
    『Java安全』利用反射调用MimeLauncher.run()触发RCE
    Python | Leetcode Python题解之第47题全排列II
    C++ string类模板
    Prometheus之node_exporter服务器采集信息泛释
    融媒体解决方案-最新全套文件
    PAT 甲级 A1107 Social Clusters
  • 原文地址:https://blog.csdn.net/chenchenchencl/article/details/127421201