校招算法笔面试 | 校招笔面试真题-找出单向链表中的一个节点,该节点到尾指针的距离为K

题目## 题目

题目链接

题解

题目难度:简单

知识点:查找、链表

解题思路:这是一道考察链表知识点的题,要求输出倒数第k个节点的值,因为此链表结构是顺着保存数据的,所以指针无法访问倒数的值。解题关键在使用两个距离相差k的指针进行数据访问,一旦第一个指针已经到最后的节点时,此时第二个指针所在的位置刚好是倒数第k个节点。

题解

第一步:创建一个链表保存数据;第二步:使用两个相距k的指针同时进行访问链表,一旦第一个到达末尾,第二个即在所求节点位置。

#include <bits stdc++.h>
using namespace std;
struct ListNode
{
    int m_nKey;
    ListNode* m_pNext;
    ListNode(int x):m_nKey(x),m_pNext(nullptr){};
};
int main()
{
    //使用一个指针head,保存目前链表的头
    ListNode* head=new ListNode(0);
    ListNode* cur=head;
    for(int i=1;i&lt;8;i++)
    {
        ListNode* temp=new ListNode(i);
        cur-&gt;m_pNext=temp;
        cur=cur-&gt;m_pNext;
    }
    int k;
    cin&gt;&gt;k;
    cur=head;
    //将两个指针距离k
    for(int i=0;i<k;i++) { cur="cur-">m_pNext;
   }
    //两个指针同时前进,直到前面的指针走完,这时head的值就是第倒数k个的节点
    while(cur)
    {
        cur=cur-&gt;m_pNext;
        head=head-&gt;m_pNext;
   }
    cout&lt;<head->m_nKey&lt;</head-></k;i++)></bits>

[题目链接](https://www.nowcoder.com/practice/596eb514664b415994c843c2e489aba8?tpId=182&tqId=325931&sourceUrl=/exam/oj&channelPut=wcsdn&fromPut=wcsdn)

## 解题思路

题目要求找出序列中的"异数",定义如下:
1. 序列中包含 $2$ 到 $16$ 进制的整数
2. 如果一个数与序列中其他所有数都不相等,则称为"异数"
3. 输入格式为"n#m",其中 $n$ 表示进制 $(1<n<17)$,$m$ 为该进制下的数值

解题思路:
1. 对每个输入的数:
   - 解析进制 $n$ 和数值 $m$
   - 将 $m$ 转换为十进制数值
2. 使用哈希表统计每个十进制值出现的次数
3. 输出只出现一次的数的原始表示形式

---

## 代码

```cpp []
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;

// 将指定进制的字符串转换为十进制数
int convertToDecimal(int base, const string& num) {
    int result = 0;
    for (char c : num) {
        int digit;
        if (c >= '0' && c <= '9') {
            digit = c - '0';
        } else {
            digit = c - 'A' + 10;
        }
        result = result * base + digit;
    }
    return result;
}

int main() {
    string input;
    vector<pair<string, int>> numbers;
    unordered_map<int, int> frequency;
    
    // 读取输入直到遇到END
    while (cin >> input && input != "END") {
        // 分割进制和数值
        int pos = input.find('#');
        int base = stoi(input.substr(0, pos));
        string num = input.substr(pos + 1);
        
        // 转换为十进制并存储
        int decimal = convertToDecimal(base, num);
        numbers.push_back({input, decimal});
        frequency[decimal]++;
    }
    
    // 输出异数
    bool found = false;
    for (const auto& p : numbers) {
        if (frequency[p.second] == 1) {
            cout << p.first << endl;
            found = true;
        }
    }
    
    if (!found) {
        cout << "None" << endl;
    }
    
    return 0;
}
import java.util.*;

public class Main {
    // 将指定进制的字符串转换为十进制数
    private static int convertToDecimal(int base, String num) {
        int result = 0;
        for (char c : num.toCharArray()) {
            int digit;
            if (c >= '0' && c <= '9') {
                digit = c - '0';
            } else {
                digit = c - 'A' + 10;
            }
            result = result * base + digit;
        }
        return result;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<String> originalInputs = new ArrayList<>();
        List<Integer> decimalValues = new ArrayList<>();
        Map<Integer, Integer> frequency = new HashMap<>();
        
        // 读取输入
        while (true) {
            String input = sc.next();
            if (input.equals("END")) break;
            
            // 分割进制和数值
            String[] parts = input.split("#");
            int base = Integer.parseInt(parts[0]);
            int decimal = convertToDecimal(base, parts[1]);
            
            originalInputs.add(input);
            decimalValues.add(decimal);
            frequency.put(decimal, frequency.getOrDefault(decimal, 0) + 1);
        }
        
        // 输出异数
        boolean found = false;
        for (int i = 0; i < originalInputs.size(); i++) {
            if (frequency.get(decimalValues.get(i)) == 1) {
                System.out.println(originalInputs.get(i));
                found = true;
            }
        }
        
        if (!found) {
            System.out.println("None");
        }
    }
}
def convert_to_decimal(base, num):
    result = 0
    for c in num:
        if c.isdigit():
            digit = int(c)
        else:
            digit = ord(c) - ord('A') + 10
        result = result * base + digit
    return result

# 存储输入和转换后的值
numbers = []  # 存储原始输入和十进制值的元组
frequency = {}  # 存储十进制值的出现频率

# 读取输入
while True:
    try:
        inp = input()
        if inp == "END":
            break
            
        # 分割进制和数值
        base, num = inp.split('#')
        base = int(base)
        
        # 转换为十进制
        decimal = convert_to_decimal(base, num)
        
        numbers.append((inp, decimal))
        frequency[decimal] = frequency.get(decimal, 0) + 1
        
    except EOFError:
        break

# 输出异数
found = False
for original, decimal in numbers:
    if frequency[decimal] == 1:
        print(original)
        found = True

if not found:
    print("None")

算法及复杂度

  • 算法:进制转换 + 哈希表统计
  • 时间复杂度: O ( N L ) \mathcal{O}(NL) O(NL) - N N N 是输入数的个数, L L L 是每个数的最大长度
  • 空间复杂度: O ( N ) \mathcal{O}(N) O(N) - 需要存储所有输入的原始形式和十进制值
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值